【问题标题】:Java Regexp: UNGREEDY flagJava 正则表达式:UNGREEDY 标志
【发布时间】:2009-10-12 00:28:47
【问题描述】:

我想将通用文本处理工具Texy! 从 PHP 移植到 Java。

此工具使用preg_match_all("/.../U") 在任何地方进行不贪婪匹配。 所以我正在寻找一个库,它有一些 UNGREEDY 标志。

知道我可以使用.*? 语法,但确实有很多正则表达式我必须覆盖,并在每个更新版本中检查它们。

我已经检查过了

  • ORO - 似乎被遗弃了
  • Jakarta Regexp - 不支持
  • java.util.regex - 不支持

有没有这样的库?

谢谢,昂德拉

【问题讨论】:

    标签: java php regex reluctant-quantifiers non-greedy


    【解决方案1】:

    更新:检查文档后,我发现了 LAZY 标志,这是非贪婪的另一个术语。但是它似乎只在 OpenJDK 中可用

    p = Pattern.compile("your regex here", LAZY);
    p.matcher("string to match")
    

    原始已弃用响应 老实说,我认为没有。

    + 的全部意义?和 *?是这样你可以选择哪些部分贪婪地做,哪些部分懒惰地做。

    贪婪是默认行为,因为这是正则表达式中 + 和 * 最常用的用法。事实上,我想不出一个正则表达式解析器可以反过来做。就像使用修饰符使某些东西变得贪婪一样,默认是惰性匹配。

    我知道这不是您正在寻找的答案,但是,我认为您能够使其工作的唯一方法是添加 ?到您的 * 和 + 。从好的方面来说,您可以使用正则表达式来帮助确定哪些需要更改。如果所有这些都需要更改,甚至可以为您进行更改。或者,您是否可以描述一种模式来识别需要更改的内容。

    【讨论】:

    • 所以你是说没有办法改变默认行为?拥有一个不能仅仅因为它是“最常见的 [...]”而改变的默认行为并不意味着拥有 switch 是一个坏主意
    • 我并不是说这不可能,甚至没有必要。我只是根据我在多种语言方面的经验来说明这一点。在提问者提到 preg_match_all("/.../U") 之前,我什至从未见过正则表达式的惰性切换。
    • 哇,当它在 OpenJDK 中时,它很有可能成为 Sun JDK!而且,希望我可以采用 OpenJDK 的实现并在 Sun JDK 中使用它。但是,你在哪里找到的?它不在文档中:jdocs.com/javase/7.b12/java/util/regex/Pattern.html(应该是 OpenJDK 的文档)。
    • 这是我找到它的地方。请注意,它被列为最终 int,通常表示标志。但它没有确切的描述。所以它可能没有实现。 docjar.com/docs/api/java/util/regex/Pattern.html
    • 不幸的是,这只是一个用于解析和处理闭包的常量。 docjar.com 从源创建文档,并显示私有范围。
    【解决方案2】:

    我建议您创建自己的修改后的 Java 库。只需将 java.util.regex 源代码复制到您自己的包中即可。

    Sun JDK 1.6 Pattern.java 类提供以下默认标志:

    static final int GREEDY     = 0;
    
    static final int LAZY       = 1;
    
    static final int POSSESSIVE = 2;
    

    您会注意到这些标志只使用了几次,而且修改起来也很简单。举个例子:

        case '*':
            ch = next();
            if (ch == '?') {
                next();
                return new Curly(prev, 0, MAX_REPS, LAZY);
            } else if (ch == '+') {
                next();
                return new Curly(prev, 0, MAX_REPS, POSSESSIVE);
            }
            return new Curly(prev, 0, MAX_REPS, GREEDY);
    

    只需更改最后一行以使用“懒惰”标志而不是 GREEDY 标志。由于您希望正则表达式库的行为类似于 PHP,这可能是最好的方法。

    【讨论】:

    • 实际上,这个 RFE 的补丁就像用从标志创建的变量替换默认返回路径中的 GREEDY 一样简单。太好了,我要向 JDK 提交补丁 :)
    【解决方案3】:

    关于检查和重新检查所有正则表达式的想法,您确定 php 和 java 库在语法上足够一致,您不必这样做吗?我首先要做的是遍历它们并编写一些测试(输入和输出)并确保它们在两种实现中的工作方式相同。然后设计一种自动运行它们的方法,您将在未来的升级和不兼容问题上得到保障。你仍然需要调整一些东西,但至少你会知道在哪里。

    【讨论】:

    • 嗯,java.util.regex 应该是 Perl5 兼容的,不包括工具中没有使用的几个特性——除了这个。当然,我已经要求 PHP 原件的作者创建一些测试来证明其他实现。
    【解决方案4】:

    您也许可以使用“com.caucho.quercus.lib.regexp.JavaRegexpModule”。 Quercus is a Java implementation of PHP,正则表达式库实现了 PHP 正则表达式 syntax and method names

    【讨论】:

      猜你喜欢
      • 2022-12-10
      • 2018-07-17
      • 2019-01-12
      • 1970-01-01
      • 2015-12-29
      • 1970-01-01
      • 2021-06-07
      • 2011-05-31
      • 1970-01-01
      相关资源
      最近更新 更多