我需要转换下一个php正则表达式:
/^ (?: 'd{1,16} | (?: 'x0A | 'x0D | ['x20-'x5A] | 'x5F | ['x61-'x7A] | 'xC2'xA0 | 'xCE'xA9 ){1,11} ) $/xsi
我是regex的新手,我发现了一个有用的链接:
http://www.regexplanet.com/advanced/java/index.html
我理解正确吗,那里我应该只粘贴php正则表达式,按"测试"和这个结果:
'/^ (?: ''d{1,16} | (?: ''x0A | ''x0D | [''x20-''x5A] | ''x5F | [''x61-''x7A] | ''xC2''xA0 | ''xCE''xA9 ){1,11} ) $/xsi'
会用Java工作吗?
您的原始模式看起来很奇怪:用'x..
编写的大多数字符都在ASCII表中。当您可以(例如)为'x0A
编写'n
,为'x0D
编写'r
等时,为什么要使用这种复杂的表示法。?它可以用一种更简单的方式编写(总是针对PHP):
/^(?:'d{1,16}|(?:'n|'r|[ -Z]|_|[a-z]|'xC2'xA0|'xCE'xA9){1,11})$/i
(我去掉了x修饰符和非有效空格。s修饰符没用。)
由于模式不区分大小写(修饰符i),[a-z]
已经包含在[ -Z]
中(包含[A-Z]
,请参阅ASCII表),并且可以删除。另外,使用字符类而不是单个字符的交替会更短、更具性能:
/^(?:'d{1,16}|(?:['n'r -Z_]|'xC2'xA0|'xCE'xA9){1,11})$/i
关于'xC2'xA0
和'xCE'xA9
:这些序列代表UTF8编码的字符NO-BREAK SPACE
和GREEK CAPITAL LETTER OMEGA
。
默认情况下,PCRE(PHP正则表达式引擎)不支持unicode,而是将字符串读取为单字节序列(每个字符一个字节)。如果添加u
修饰符或使用(*UTF8)
启动模式,则可以将字符串读取为UTF8编码的字符串。在您的模式中,没有u
修饰符,因此每个字节都被视为一个字符。
Java正则表达式引擎默认支持unicode,不逐字节读取字符串,而是逐字符读取。
为了使从PHP到Java的"翻译"更容易,我将用u修饰符重写PHP模式:
/^(?:[0-9]{1,16}|['n'r -Z_'x{00A0}'x{03A9}]{1,11})$/iu
描述每个字节的'xC2'xA0
现在被'x{00A0}
取代,其中00A0
是字符NO-BREAK SPACE
的unicode代码点。欧米茄也是如此(查看unicode表)
请注意,u修饰符将'd
扩展到unicode表中的所有数字。为了防止这种副作用,我把它换成了[0-9]
。
要编写Java模式,您只需要用'u....
语法替换'x{....}
语法,并使用CASE_INSENSITIVE选项:
^(?:[0-9]{1,16}|['n'r -Z_'u00A0'u03A9]{1,11})$
(不要忘记转义反斜杠)