2017-01-04 4 views
2

Ich verwende "\\b(\\w+)(\\W+\\1\\b)+" zusammen mit input = input.replaceAll(regex, "$1");, um doppelte Wörter in einer Zeichenfolge zu finden und die Duplikate zu entfernen. Zum Beispiel würde die Zeichenfolge input = "for for" zu "for" werden.Java regex (? I) vs Pattern.CASE_INSENSITIVE

Allerdings ist es versagt „Hallo hallo“ in „Hallo“ zu drehen, obwohl ich Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);

verwendet habe ich es durch die Verwendung "(?i)\\b(\\w+)(\\W+\\1\\b)+" korrigieren kann, aber ich möchte wissen, warum dies notwendig ist? Warum muss ich das Flag (? I) verwenden, wenn ich bereits Pattern.CASE_INSENSITIVE angegeben habe?

Heres der vollständige Code für Klarheit:

import java.util.Scanner; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public class DuplicateWords { 

public static void main(String[] args) { 

    String regex = "\\b(\\w+)(\\W+\\1\\b)+"; 
    Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); 

    Scanner in = new Scanner(System.in); 
    int numSentences = Integer.parseInt(in.nextLine()); 

    while (numSentences-- > 0) { 
     String input = in.nextLine(); 

     Matcher m = p.matcher(input); 

     // Check for subsequences of input that match the compiled pattern 
     while (m.find()) { 
      input = input.replaceAll(regex, "$1"); 
     } 

     // Prints the modified sentence. 
     System.out.println(input); 
    } 
    in.close(); 
} 
} 

Antwort

1

Ihr Problem ist, dass Sie einen regulären Ausdruck mit CASE_SENSITIVE Flagge sind definiert, aber ihn nicht richtig in replaceAll Verfahren.

Sie können auch (?i) in der Mitte der regex verwenden für Fall Spiel von Rückverweis \1 wie diese ignorieren:

String repl = "Hello hello".replaceAll("\\b(\\w+)(\\W+(?i:\\1)\\b)+", "$1"); 
//=> Hello 

Und dann Matcher.replaceAll später verwenden.

Arbeits-Code: (i)

public class DuplicateWords { 

    public static void main(String[] args) { 

     String regex = "\\b(\\w+)(\\W+(?i:\\1)\\b)+"; 
     Pattern p = Pattern.compile(regex); 

     // OR this one also works 
     // String regex = "\\b(\\w+)(\\W+\\1\\b)+"; 
     // Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); 

     Scanner in = new Scanner(System.in); 
     int numSentences = Integer.parseInt(in.nextLine()); 

     while (numSentences-- > 0) { 
      String input = in.nextLine(); 

      Matcher m = p.matcher(input); 

      // Check for subsequences of input that match the compiled pattern 
      if (m.find()) { 
       input = m.replaceAll("$1"); 
      } 

      // Prints the modified sentence. 
      System.out.println(input); 
     } 
     in.close(); 
    } 
} 
+0

So bewirkt nur den Block unmittelbar nach dem (in diesem Fall \\ 1) und nicht die ganze Regex? – Paddy

+0

Ja, das ist richtig – anubhava

+0

Ich verstehe immer noch nicht, warum ich (? I) überhaupt verwenden muss. Sollte Pattern.CASE_INSENSITIVE nicht ausreichend sein? – Paddy