Java 边界匹配器正则表达式(\b)上的以下代码段出现问题
我的意见:Java 边界匹配器正则表达式(\b)上的以下代码段出现问题,java,regex,set,Java,Regex,Set,我的意见: 1. end 2. end of the day or end of the week 3. endline 4. something 5. "something" end 基于以上讨论,如果我尝试使用此代码段替换单个字符串,它会成功地从行中删除相应的单词 public class DeleteTest { public static void main(String[] args) { // TODO Auto-generated me
1. end
2. end of the day or end of the week
3. endline
4. something
5. "something" end
基于以上讨论,如果我尝试使用此代码段替换单个字符串,它会成功地从行中删除相应的单词
public class DeleteTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
File file = new File("C:/Java samples/myfile.txt");
File temp = File.createTempFile("myfile1", ".txt", file.getParentFile());
String delete="end";
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(temp)));
for (String line; (line = reader.readLine()) != null;) {
line = line.replaceAll("\\b"+delete+"\\b", "");
writer.println(line);
}
reader.close();
writer.close();
}
catch (Exception e) {
System.out.println("Something went Wrong");
}
}
}
如果我使用上述代码段,我的输出:(也是我的预期输出)
但是,当我包含更多要删除的单词时,并且出于此目的,当我使用Set时,我使用以下代码段:
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
File file = new File("C:/Java samples/myfile.txt");
File temp = File.createTempFile("myfile1", ".txt", file.getParentFile());
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(temp)));
Set<String> toDelete = new HashSet<>();
toDelete.add("end");
toDelete.add("something");
for (String line; (line = reader.readLine()) != null;) {
line = line.replaceAll("\\b"+toDelete+"\\b", "");
writer.println(line);
}
reader.close();
writer.close();
}
catch (Exception e) {
System.out.println("Something went Wrong");
}
}
你们能帮我吗
问题在于您没有创建正确的正则表达式来替换集合中的单词
“\\b”+toDelete+“\\b”
将生成此字符串\b[结束,某物]\b
,这不是您需要的
要解决此问题,您可以执行以下操作:
for(String del : toDelete){
line = line.replaceAll("\\b"+del+"\\b", "");
}
这样做的目的是遍历集合,从每个单词中生成一个正则表达式,并从行
字符串中删除该单词
另一种方法是从集合中的所有单词生成一个正则表达式
例如:
这将生成一个类似以下内容的正则表达式:(\bend\b)|(\bsomething\b)
您需要使用
String.join("|", toDelete)
并用作
line = line.replaceAll("\\b(?:"+String.join("|", toDelete)+")\\b", "");
这个图案看起来像
\b(?:end|something)\b
看。这里,(?:…)
是一个非捕获组,用于对多个备选方案进行分组,而无需为捕获创建内存缓冲区(您不需要它,因为您删除了匹配项)
或者,最好在进入循环之前编译正则表达式:
Pattern pat = Pattern.compile("\\b(?:" + String.join("|", toDelete) + ")\\b");
...
line = pat.matcher(line).replaceAll("");
更新:
要允许匹配可能包含特殊字符的整个“单词”,您需要模式。引用这些单词以转义这些特殊字符,然后需要使用明确的单词边界(?而不是初始的\b
,以确保前面和之间没有单词字符(?!\w)
负前瞻,而不是最后的\b
,以确保匹配后没有单词char
在Java 8中,您可以使用以下代码:
Set<String> nToDel = new HashSet<>();
nToDel = toDelete.stream()
.map(Pattern::quote)
.collect(Collectors.toCollection(HashSet::new));
String pattern = "(?<!\\w)(?:" + String.join("|", nToDel) + ")(?!\\w)";
Set nToDel=newhashset();
nToDel=toDelete.stream()
.map(模式::引号)
.collect(Collectors.toCollection(HashSet::new));
String pattern=“(?谢谢Wiktor。你能建议一种在正则表达式模式中添加括号和特殊字符的方法吗?@venk:你的意思是在toDelete
项中有非单词(非字母/数字/)?那么你基于单词边界的方法可能找不到匹配项(如果这些非单词字符出现在开头/结尾,如\b(?:+end | something-\b
)。您需要在所有项目上运行模式。引用,然后使用(?和(?!\w)<代码> >而不是<代码> \b/c> S.@ vnk:请参阅更新后的答案。请考虑接受它是否适合您。谢谢您的解决方案。如预期的那样工作:谢谢提图斯。你能建议一种在正则表达式中添加括号和特殊字符的方法吗?@venk你需要使用“`”对这些字符进行转义。你可以找到更多关于你在使用Java 8还是Java 7的详细信息?我在使用Java 8
\b(?:end|something)\b
Pattern pat = Pattern.compile("\\b(?:" + String.join("|", toDelete) + ")\\b");
...
line = pat.matcher(line).replaceAll("");
Set<String> nToDel = new HashSet<>();
nToDel = toDelete.stream()
.map(Pattern::quote)
.collect(Collectors.toCollection(HashSet::new));
String pattern = "(?<!\\w)(?:" + String.join("|", nToDel) + ")(?!\\w)";