我正在尝试将此正则表达式转换为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最终支持命名组,因此您不必在那里折衷。