将带有条件的正则表达式转换为Java

时间:2012-06-03 22:07:37

标签: java regex

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

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

我当然知道条件不受支持。直接翻译 导致例外。因此,我想知道如何解决问题。

谢谢,

1 个答案:

答案 0 :(得分:2)

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

^(\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-branch中的[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。 (无论如何,这出现了什么语言?)你必须这样做的方法是用or-branch展开条件,其中两个案例都被覆盖。

我对整个模式有点怀疑,因为它似乎不合理。应该赞赏一些它应该匹配的样本输入。

我不能强调的一点是,我提供的/x - 正则表达式的扩展版本是你应该永远写过这些东西的唯一方法。没有空格,缩进,逻辑组和评论的那个卑鄙的小说是完全不可接受的。这样的事情永远不应该通过代码审查。他们是可憎的。

而且他们不一定是。我求求你总是总是使用/x模式来处理任何非平凡长度和复杂度的正则表达式,就像这个一样。试着想一想那些将会追随你的人,希望在他们这样做之前。

最后,我想知道为什么这会使用编号组而不是更多的助记符命名组,这些组更加健壮。加上Java 7最终支持命名组,因此您不必在那里妥协。