将php正则表达式转换为java

时间:2015-12-17 10:38:06

标签: java php regex


我需要转换下一个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吗?

1 个答案:

答案 0 :(得分:3)

您的原始模式看起来很奇怪:用\x..编写的大多数字符都在ASCII表中。为什么在为\n\x0A \r等编写(例如)\x0D时使用此复杂表示法?它可以用更简单的方式编写(总是用于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 SPACEGREEK 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代码点。欧米茄也是如此。 (请查看the unicode table

请注意,u修饰符将\d扩展为unicode表中的所有数字。为了防止这种副作用,我已将其替换为[0-9]

要编写Java模式,您只需要使用\x{....}语法替换\u....语法并使用CASE_INSENSITIVE选项:

^(?:[0-9]{1,16}|[\n\r -Z_\u00A0\u03A9]{1,11})$

(别忘了逃避反斜杠)