我正在使用"\\b(\\w+)(\\W+\\1\\b)+"withinput = input.replaceAll(regex, "$1");在字符串中查找重复的单词并删除重复项。例如,字符串 input = "for for for" 将变为 "for"。
然而,即使我使用过它也无法将“Hello hello”变成“Hello” Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
我可以通过使用来纠正它,"(?i)\\b(\\w+)(\\W+\\1\\b)+"但我想知道为什么这是必要的?当我已经指定了 Pattern.CASE_INSENSITIVE 时,为什么我必须使用 (?i) 标志?
为了清楚起见,这里是完整的代码:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
您的问题是您正在定义带有CASE_SENSITIVE标志的正则表达式,但没有在replaceAll方法中正确使用它。
您还可以(?i)在正则表达式的中间使用忽略反向引用的大小写匹配,\1如下所示:
String repl = "Hello hello".replaceAll("\\b(\\w+)(\\W+(?i:\\1)\\b)+", "$1");
//=> Hello
Run Code Online (Sandbox Code Playgroud)
然后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();
}
}
Run Code Online (Sandbox Code Playgroud)