2

与 word-boundary 结合使用时,我遇到了 Java Regex 的一个奇怪问题\b。通读Oracle - RegexBoundsRegularExpressions - WordBoundaries

下面是我的正则表达式(Java 字符串)(用于电子邮件地址)

"\\b[A-Z0-9._!#$%&'*+-/=?^`{}|~]+@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}$"

此正则表达式匹配电子邮件test$@example.com但不匹配$test@example.com

但是,当我删除\b(Java String \\b) 时,它与这两个电子邮件匹配。正则表达式中的所有特殊字符都是这种情况。

\b正则表达式的排序发生了什么?我虽然[A-Z0-9._!#$%&'*+-/=?^`{}|~]+应该以任何顺序匹配文本,而不管\b

代码片段:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ValidationUtil {

    private static final String EMAIL_ADDRESS_REGEX = "\\b[A-Z0-9._!#$%&'*+-/=?^`{}|~]+@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}$";
    private static final Pattern EMAIL_ADDRESS_PATTERN = Pattern.compile(EMAIL_ADDRESS_REGEX, Pattern.CASE_INSENSITIVE);

    public static boolean isValidEmail(String email) {
        if (email == null) {
            return false;
        }
        Matcher matcher = EMAIL_ADDRESS_PATTERN.matcher(email);
        return matcher.matches();
    }
}

在这个问题之后,我将正则表达式验证移至apache-commons EmailValidator。但仍然很好奇为什么会出现这种奇怪的行为。

我浏览了许多有关 问题的 stackoverflow 主题\b,但找不到相关的主题。

4

2 回答 2

3

引用您链接到的页面:

有资格作为单词边界的三个不同位置:

  • 在字符串的第一个字符之前,如果第一个字符是单词字符。
  • ...

第一个字符 ,$不是单词字符,因此\b在字符串的开头不匹配,因此整个正则表达式不匹配。

于 2015-01-05T22:16:52.493 回答
2

首先,您需要在字符类的第一个或最后一个位置放置未转义的连字符。其次,您之前不能使用单词边界,$因为$它不被视为单词字符。

这个修改后的正则表达式后视应该适合你:

(?<!\w)[\w.!#$%&'*+/=?^`{}|~-]+@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}$

正则表达式演示

这里(?<!\w)的意思是如果前面没有单词字符,则匹配。

于 2015-01-05T22:19:29.950 回答