Java 使用 \b 的正则表达式排序
Java Regex Ordering with \b
当 Java 正则表达式与字边界 \b
结合使用时,我遇到了一个奇怪的问题。
通读 Oracle - RegexBounds and RegularExpressions - WordBoundaries
下面是我的正则表达式(Java 字符串)(用于电子邮件地址)
"\b[A-Z0-9._!#$%&'*+-/=?^`{}|~]+@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}$"
此正则表达式匹配电子邮件 test$@example.com
但不匹配 $test@example.com
。
但是,当我删除 \b
(Java 字符串 \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。但仍然很好奇为什么会有这种奇怪的行为。
我浏览了许多关于 \b
问题的 Whosebug 主题,但找不到相关主题。
引用 page 你 link 给:
There are three different positions that qualify as word boundaries:
- Before the first character in the string, if the first character is a word character.
- ...
第一个字符 $
不是单词字符,因此 \b
在字符串的开头不匹配,因此不匹配整个正则表达式。
首先,您需要将未转义的连字符放在字符 class 的第一个或最后一个位置。其次 您不能在 $
之前使用单词边界,因为 $
不被视为单词字符。
这个修改后的正则表达式基于后视应该适合你:
(?<!\w)[\w.!#$%&'*+/=?^`{}|~-]+@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}$
RegEx Demo
这里(?<!\w)
表示如果前面没有单词字符则匹配
当 Java 正则表达式与字边界 \b
结合使用时,我遇到了一个奇怪的问题。
通读 Oracle - RegexBounds and RegularExpressions - WordBoundaries
下面是我的正则表达式(Java 字符串)(用于电子邮件地址)
"\b[A-Z0-9._!#$%&'*+-/=?^`{}|~]+@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}$"
此正则表达式匹配电子邮件 test$@example.com
但不匹配 $test@example.com
。
但是,当我删除 \b
(Java 字符串 \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。但仍然很好奇为什么会有这种奇怪的行为。
我浏览了许多关于 \b
问题的 Whosebug 主题,但找不到相关主题。
引用 page 你 link 给:
There are three different positions that qualify as word boundaries:
- Before the first character in the string, if the first character is a word character.
- ...
第一个字符 $
不是单词字符,因此 \b
在字符串的开头不匹配,因此不匹配整个正则表达式。
首先,您需要将未转义的连字符放在字符 class 的第一个或最后一个位置。其次 您不能在 $
之前使用单词边界,因为 $
不被视为单词字符。
这个修改后的正则表达式基于后视应该适合你:
(?<!\w)[\w.!#$%&'*+/=?^`{}|~-]+@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}$
RegEx Demo
这里(?<!\w)
表示如果前面没有单词字符则匹配