我正在使用常见的正则表达式验证电子邮件。模式是:
(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*")@((?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$)|\[(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\]$
以防万一,我在java中添加了所有\ escaping,所以这是java评估的最终模式。它适用于普通的在线正则表达式评估程序,但在Java中运行时会抛出
java.util.regex.PatternSyntaxException:索引103附近的非法/不支持转义序列
这是\ 177代码。为什么这样,为什么该代码是非法的,为什么它在在线验证器中起作用?
答案 0 :(得分:4)
The javadoc of Pattern
在这里给出了答案;引用:
\0n The character with octal value 0n (0 <= n <= 7)
\0nn The character with octal value 0nn (0 <= n <= 7)
\0mnn The character with octal value 0mnn (0 <= m <= 3, 0 <= n <= 7)
出现八进制转义序列的唯一有效方法是上面的。
如果您为\1xx
编写xx
,则会将其解释为\1
然后xx
,其中\1
是对第一个...37!#-\[\]-\177]|\\
^^ HERE
的反向引用捕获正则表达式组...
除非在您的情况下,索引103位于:
\0177
你是一个角色类;并且你不能在字符类中使用反向引用。因此,正则表达式引擎试图将其解释为转义序列,如上所述,这是非法的。因此消息。
将其替换为{{1}},您的问题就会得到解决。
作为旁注,验证带有正则表达式的电子邮件虽然很常见,但也是一个非常糟糕的主意。请改用javax.mail,它可以使用InternetAddress
验证邮件地址。
[进一步说明:虽然上面的链接是Java EE,但实际上你可以将javamail作为一个独立的jar添加到你的项目中;快速的maven搜索会告诉你]
答案 1 :(得分:0)
内联正则表达式验证器往往会产生误导,因为有许多不同类型的正则表达式。您需要一个Java正则表达式,但您的验证器显然正在测试相关但不同的风格。
针对您的具体问题:从the documentation for java.util.regex.Pattern
可以看出,八进制转义必须以\0
开头,但之后最多可以有三位数。因此,请将\177
更改为\0177
。
答案 2 :(得分:0)
在课堂之外,Java将八进制视为\0377
,以区别于它
反向引用。
其他引擎将采用\377
形式,但使用内部捕获组
在这一点上的认可,以区别于反向引用
这些其他引擎不会识别类中的\nnn
形式,
但为此提供了一个八进制括号形式\o{nnn}
。
据我所知,您可以尝试\0377
内部课程,看看是否有
这是有效的,否则我不知道Java是否在课堂上识别八进制。