我正在尝试匹配以下正则表达式:
\b(?:mr|mrs|ms|miss|messrs|mmes|dr|prof|rev|sr|jr|&|and)\.?\b
换句话说,一个词边界后跟上述任何字符串(可选后跟一个句点字符),然后是一个词边界。
我正在尝试在 Java 中匹配它,但与号不匹配。例如:
Pattern p = Pattern.compile(
"\\b(?:mr|mrs|ms|miss|messrs|mmes|dr|prof|rev|sr|jr|&|and)\\.?\\b",
Pattern.CASE_INSENSITIVE);
String result = p.matcher("mr one and mrs.two and three & four").replaceAll(" ");
System.out.println("["+result+"]");
它的输出是:[ one two three & four]
我也在 regex101 上试过这个,和号再次不匹配:https://regex101.com/r/klkmwl/1
转义与号并没有什么区别,我尝试使用十六进制转义序列 \x26
代替与号(如 this question 中建议的那样)。为什么这不匹配?
答案 0 :(得分:3)
您的正则表达式将匹配一个&符号,如果它位于单词字符之间,例如three&four
,见 this regex demo。发生这种情况是因为 \b
在非字字符之前需要一个字字符紧跟在它之前出现。此外,由于在可选点后面有一个 \b
,因此点和与符号仅在左侧紧接有字符字符时才匹配。
您需要重新编写模式,以便将单词边界应用于单词而不是符号:
Pattern p = Pattern.compile(
"(?:\\b(?:mr|mrs|ms|miss|messrs|mmes|dr|prof|rev|sr|jr|and)\\b|&)\\.?",
Pattern.CASE_INSENSITIVE);
答案 1 :(得分:2)
问题是由于使用了单词边界。像 &
这样的非单词字符前后没有单词边界。
您可以使用环视代替单词边界:
(?<!\w)(?:[jsdm]r|mr?s|miss|messrs|mmes|prof|re|&|and)\.?(?!\w)
(?<!\w)
:确保前一个字符不是单词字符(?!\w)
:确保下一个字符不是单词字符注意您的正则表达式中的一些调整以使其更短。