我正在尝试将此正则表达式转换为Java:

^(\s*([<>]=?)?\s*!?(?:(2)[0-9]{1,5}|[0-9\*]{1,5})\s*(&|$))*


我当然知道不支持条件。直接翻译
导致异常。因此,我想知道如何解决问题的想法。

谢谢,

最佳答案

首先,我认为您的模式中有一个错误:

^(\s*([<>]=?)?\s*!?(?:(2)[0-9]{1,5}|[0-9\*]{1,5})\s*(&|$))*


在对第2组进行测试时,您似乎冒了一个冒号,但该冒号不会做您想要的。那应该是:

^(\s*([<>]=?)?\s*!?(?(2)[0-9]{1,5}|[0-9\*]{1,5})\s*(&|$))*


但是还有其他奇怪的地方对我来说没有多大意义。我将在(?x)模式下重写您的模式,以便我们对其进行拆解并尝试对其进行一些理解。哦,我会在条件的or分支中消除[0-9\*]中多余的反斜杠,因为它实际上应该只是[0-9*]

这产生了:

(?x)                       # enable comments and whitespace
^                          # anchor to beginning of string
(                          # begin GROUP #1 {
    \s *                   #     any amount of whitespace, including none
    (                      #     begin GROUP #2 {
        [<>]               #        exactly one of either kind of pointy bracket
        = ?                #        optional equals sign
    ) ?                    #     } end GROUP #2, make optional
    \s *                   #     any amount of whitespace, including none
    ! ?                    #     optional exclamation point
    (?(2)                  #     if GROUP#2 is defined {
          [0-9]   {1,5}    #         then: 1-5× ASCII digits
     |    [0-9*]  {1,5}    #         else: 1-5× of either star or ASCII digit
    )                      #     } end ifdef GROUP#2
    \s *                   #     any amount of whitespace, including none
    (                      #     begin GROUP#3 {
        &                  #        either:  an ampersand
      | $                  #        or else: end of string
    )                      #     } end GROUP#3
) *                        # } end GROUP #1, make optional but allow repeats


据我所知,这实际上是您要做的。我为什么不知道为什么要这么做,因为那里有些东西看起来很奇怪。

例如,为什么将重复运算符应用于第一个捕获组?它不会保留所有重复,只有最后一次。

另一个问题是为什么要允许第一组的零重复?就像*所有可能的字符串由模式^a*匹配的方式一样,所有可能的字符串也与模式匹配。这似乎没有用。

最后,使用“&”号或字符串结尾在结尾处很奇怪。

如果最初的发帖人可以阐明他的意图,那么我将把它翻译成与Java正则表达式兼容的东西,它们不支持您在此使用的条件构造,而Perl,PHP,PCRE和C♯都支持但不支持Java。 。 (无论如何,这是用什么语言表达出来的?)您必须这样做的方法是使用“或”分支展开有条件的条件,其中涵盖了两种情况。

我对整个模式有点怀疑,因为它似乎并不明智。它应该匹配一些样本输入将不胜感激。

我不能过分强调的一件事是,我提供的正则表达式的/x扩展版本是您永远,永远,永远应该编写这些东西的唯一方法。没有空格,缩进,逻辑组和注释的乱七八糟的想法是完全不能接受的。这样的事情永远都不能通过代码审查。他们是可憎的。

而且他们不必如此。求求您,对于这种长度和复杂性不高的正则表达式,总是使用/x模式,就像这样。试着想想会在你之后追随你的人。

最后,我想知道为什么它使用编号组而不是更易记的命名组,后者更健壮。再加上Java 7最终支持命名组,因此您不必在那里折衷。

07-24 18:56
查看更多