【问题标题】:Regex conversion from java to php从 java 到 php 的正则表达式转换
【发布时间】:2011-11-04 21:28:03
【问题描述】:

我在 php 中有一个正则表达式,我需要将它转换为 java。 有可能这样做吗?如果是,我该怎么办?

提前致谢

$region_pattern = "/<a href=\"#\"><img src=\"images\/ponto_[^\.]+\.gif\"[^>]*>[&nbsp;]*<strong>(?P<neighborhood>[^\(<]+)\((?P<region>[^\)]+)\)<\/strong><\/a>/i" ;

【问题讨论】:

标签: java php regex


【解决方案1】:

从任何正则表达式到 java 的典型转换是:

  • 排除模式分隔符 => 删除开头和结尾 /
  • 删除标志,这些标志应用于Pattern 对象,这是尾随i。您应该将其放在 Pattern 对象的初始化中,或者将其添加到正则表达式中,例如(?i)&lt;regex&gt;
  • \\替换所有\\在java中已经有含义(在字符串中转义),要在java中的正则表达式中使用反斜杠,你必须使用\\而不是\,所以\w 变成了\\w。并且\\ 变为\\\\

上面的正则表达式会变成

Pattern.compile("<a href=\"#\"><img src=\"images\\/ponto_[^\\.]+\\.gif\"[^>]*>[&nbsp;]*<strong>(?P<neighborhood>[^\\(<]+)\\((?P<region>[^\\)]+)\\)<\\/strong><\\/a>", Pattern.CASE_INSENSITIVE);

但是这会失败,我认为这是因为?P 是一个修饰符,我不知道它存在于 Java 中,所以它是一个无效的正则表达式。

【讨论】:

  • 内联修饰符语法采用(?i)regex 的形式(模式的其余部分处于打开状态,或者直到用(?-i) 关闭)或(?i:regex)(模式仅在封闭组内打开) . ?P 是 Python 风格的命名组语法的一部分,它在 PHP 中也有效,但在 Java 中无效(但请参阅我的答案以获取替代方案)。
  • 啊,谢谢,我认为你可以不把它放在括号之间,而是把它放在前面。我从不使用它,总是把它放在我的 Pattern 构造中
【解决方案2】:

原始正则表达式存在一些问题,必须首先清除。首先是[&amp;nbsp;],它匹配&amp;nbsp; 中的一个字符。要匹配实际的不间断空格字符,您应该使用\xA0

那里还有很多不需要的反斜杠。您可以通过将正则表达式分隔符更改为 / 以外的其他内容来摆脱一些;不需要其他的,因为它们在字符类中,大多数元字符在其中失去了特殊含义。剩下的就是这个 PHP 正则表达式:

"~<a href=\"#\"><img src=\"images/ponto_[^.]+\.gif\"[^>]*>\xA0*<strong>(?P<neighborhood>[^(<]+)\((?P<region>[^)]+)\)</strong></a>~i"

有三件事使这个正则表达式与 Java 不兼容。一个是分隔符(最初是/,上面的版本中是~)以及尾随的i 修饰符。 Java 根本不使用正则表达式分隔符,所以只需删除它们。可以使用正则表达式开头的内联形式(?i) 将修饰符移动到正则表达式本身。 (顺便说一句,这也适用于 PHP。)

接下来是反斜杠。用于转义引号的那些保持原样,但所有其他的都加倍,因为 Java 对字符串文字中的转义序列更加严格。

最后是命名组。在 Java 6 之前,完全不支持命名组。 Java 7 支持它们,但它们使用 .NET 青睐的较短的 (?&lt;name&gt;...) 语法, 不是 Pythonesque (?P&lt;name&gt;...) 语法。 (顺便说一下,较短的(?&lt;name&gt;...) 版本也可以在 PHP 中使用((?'name'...) 也应该在 .NET 中引入)。

因此,您的正则表达式的 Java 7 版本将是:

"(?i)<a href=\"#\"><img src=\"images/ponto_[^.]+\\.gif\"[^>]*>\\xA0*<strong>(?<neighborhood>[^(<]+)\\((?<region>[^)]+)\\)</strong></a>"

对于 Java 6 或更早版本,您可以使用:

"(?i)<a href=\"#\"><img src=\"images/ponto_[^.]+\\.gif\"[^>]*>\\xA0*<strong>([^(<]+)\\(([^)]+)\\)</strong></a>"

...您必须使用数字而不是名称来指代捕获的组。

【讨论】:

    【解决方案3】:

    REGEX 是 REGEX,与语言无关。您发布的 REGEX 将适用于 Java 和 PHP。您确实需要进行一些调整,因为两种语言所采用的模式并不完全相同(尽管模式本身适用于两种语言)。

    需要考虑的要点

    • 您应该知道 Java 的 Pattern 对象应用标志,而不必在模式字符串本身上指定它们。
    • 也不应包含分隔符。只有模式本身。

    【讨论】:

    • @Ben 怎么样?这种模式在 Java 上会在哪里失败?
    • 我在 java 正则表达式测试器上试过了,我得到了一个模式语法异常
    • @Ben 我也很想知道。
    • @alexandre 在这种情况下,您可能在 REGEX 模式中遇到实际错误?你是怎么测试的?
    • 双重转义,不应以/ 开头和结尾,标志应用于Pattern 对象,以不兼容开始。转义字符的修复将是最有效的,因为在 java 正则表达式中也有三重和四重转义。相信我,任何在 Perl 或 PHP 中工作的正则表达式在简单的复制粘贴后都不会在 Java 中工作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-02
    • 1970-01-01
    • 2015-03-21
    • 1970-01-01
    相关资源
    最近更新 更多