快速射击,自由间距,可能远没有效率(首先,因为单个范围会在发现后面没有'|'时使正则表达式回溯) - 请参阅下面的版本2,它是(我相信)更有效率:
^ # Start of string
(?: # Start group, non-capturing
[([] # '(' or '['
\s* # optional whitespace
[0-9]+ # at least one digit 0-9
(?:\.[0-9]+)? # optionally '.' followed by at least one digit 0-9
\s* # optional whitespace
, # ','
\s* # optional whitespace
[0-9]+ # at least one digit 0-9
(?:\.[0-9]+)? # optionally '.' followed by at least one digit 0-9
\s* # optional whitespace
[)\]] # ')' or ']'
\s* # optional whitespace
\| # '|'
\s* # optional whitespace
)* # all the above may appear 0 or more times
[([] # The remainder is exactly the same as the group above,
\s* # used for a single range or the last range -
[0-9]+ # i.e., a range NOT followed by '|' - of a multi range.
(?:\.[0-9]+)?
\s*
,
\s*
[0-9]+
(?:\.[0-9]+)?
\s*
[)\]]
$ # end of string
这将匹配例如:
[1.5, 3]
[23.7, 3.70)
[2.9 , 3]|[3,2)
[1.5, 4] | [6.9, 9.3) | [10, 11]
(1.5, 3]
[23.7, 3.70)
(1.5, 5.0)
但不是:
[23.7, 3.70) | (7, 9) | // trailing OR
| [23.7, 3.7] // leading OR
注意,它并不能保证第二个数字实际上是高于第一。为此,我推荐将其留给/ a分析器 - 或者添加捕获组并在正则表达式之外处理它们。
VERSION 2
这应该是更有效的,由于较少回溯 - 它基本上改变从:
(任何数量的范围,随后的|),接着是一系列
...至:
的范围内,接着(任何数量的前面有范围的|)
ETA:为了解释,版本1开始时检查“的范围内,接着|”。
如果我们只有一个范围,那就是浪费时间。当它到达“|”它将重新开始,检查正则表达式的第二部分 - 即是否存在,而不是“所需的范围|”?
在版本2中,我们开始检查“范围”。这意味着,如果只有一个范围,它将成功,不会有任何回溯。如果我们给它一些乱码,例如hello
,它会立即失败,因为它现在知道第一个字符必须是(
或[
- 它不是可选的。而在版本1中,由于第一部分是可选的,因此必须检查正则表达式的第二部分以确保失败。
在几乎所有其他情况下(我测试过)版本2匹配 - 或无法匹配 - 以较少的步骤。
这里,因为它基本上是相同的正则表达式与某些部分交换,我反而把一个例子匹配的评论:
^
[([] # (
\s* #
[0-9]+ # 3
(?:\.[0-9]+)? # .90
\s* #
, # ,
\s* #
[0-9]+ # 43
(?:\.[0-9]+)? # .2
\s* #
[)\]] # ]
#
(?: #
\s* #
\| # |
\s* #
#
[([] # [
\s* #
[0-9]+ # 55
(?:\.[0-9]+)? # .20
\s* #
, # ,
\s* #
[0-9]+ # 2
(?:\.[0-9]+)? # .91
\s* #
[)\]] #)
)*
$
比赛和非比赛应该是相同的版本1
只是一个想法 - 我倾向于不喜欢“不这样做”作为对问题的回答 - 但是:既然你说“如果解析器读取格式不正确的表达式,[它]会抛出异常” - 如果可能的话,IMO的最佳方法是让解析器完成它的工作,捕获异常并将其用作验证结果,而不是执行自己的正则表达式,这可能实际上最终会导致s解析器的东西无论如何都会失败。话虽如此,我会看看(如果有人不打我的话)。 – JimmiTh
@JimmiTh - 我认为OP基本上希望将表达式“编译”为正则表达式。也许我读错了? – JDB
如果我理解正确,那么你正在尝试做的事情会导致一个可怕的丑陋和无效的正则表达式。请参阅http://stackoverflow.com/q/17604016/211627。另外,正则表达式是平台不可知的,就像C++是平台不可知的一样......离“Hello world”太远而且你很快遇到了特定于平台的实现。 – JDB