正则表达式与与号不匹配

时间:2021-06-23 09:45:30

标签: java regex

我正在尝试匹配以下正则表达式:

\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 中建议的那样)。为什么这不匹配?

2 个答案:

答案 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);

参见regex demo online

答案 1 :(得分:2)

问题是由于使用了单词边界。像 & 这样的非单词字符前后没有单词边界。

您可以使用环视代替单词边界:

(?<!\w)(?:[jsdm]r|mr?s|miss|messrs|mmes|prof|re|&|and)\.?(?!\w)

Updated RegEx Demo

  • (?<!\w):确保前一个字符不是单词字符
  • (?!\w):确保下一个字符不是单词字符

注意您的正则表达式中的一些调整以使其更短。