2017-01-04 5 views
2

Я использую "\\b(\\w+)(\\W+\\1\\b)+" вместе с input = input.replaceAll(regex, "$1");, чтобы найти повторяющиеся слова в строке и удалить дубликаты. Например, строка input = "for for for" станет "for".Java regex (? I) vs Pattern.CASE_INSENSITIVE

Однако это не удается превратить «Привет привет» в «Привет», хотя я использовал Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);

Я могу это исправить с помощью "(?i)\\b(\\w+)(\\W+\\1\\b)+", но я хочу знать, почему это необходимо? Почему я должен использовать флаг (? I), когда я уже указал Pattern.CASE_INSENSITIVE?

Heres полный код для ясности:

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(); 
} 
} 

ответ

1

Ваша проблема заключается в том, что вы определяете регулярное выражение с CASE_SENSITIVE флагом, но не использовать его правильно в replaceAll методе.

Вы также можете использовать (?i) в середине регулярного выражения для случая проигнорировать матч обратной ссылки \1 так:

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

И затем использовать Matcher.replaceAll позже.

Рабочий код: (? Я)

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

Так влияет только блок сразу после него (в этом случае \\ 1), а не весь регулярное выражение? – Paddy

+0

Да, это правильно – anubhava

+0

Я все еще не понимаю, почему я должен использовать (? I) вообще. Should'nt Pattern.CASE_INSENSITIVE достаточно? – Paddy