如何匹配任何字符的字符串(包括特殊字符),除了在较大的表达式中前面没有反斜杠的冒号外?

时间:2014-07-17 23:24:59

标签: java regex regex-lookarounds

免责声明:我认为这不是What's the regex to match anything except a double quote not preceded by a backslash?的副本,因为OA已经分隔了他/她可以使用的双引号。

我正在尝试匹配Java中的单行字符串,该字符串在伪代码中采用以下形式,其中[any!=:]是“”除了没有前面的反斜杠的冒号之外的任何字符中的至少一个的缩写”。

[any!=:]::[any!=:]:[any!=:]

我不擅长正则表达式,但我检查了负面的背后隐藏并提出了(不是Java,而是常规正则表达式):

[^(?<!\\):]+:{2}[^(?<!\\):]+:[^(?<!\\):]+

这与

类似

(1) asd::asd:asd

匹配,例如

(2) asd\:asd::asd\:asd:ads\:asd(但是,它应该)。

accepted answer与上面提到的问题联系起来,我也尝试了以下内容。

([^(?<!\\):]|\\:)+:{2}([^(?<!\\):]|\\:)+:([^(?<!\\):]|\\:)+

这适用于(2),有些但不是所有特殊字符(根据RegexPlanet)。 [c]组合中使用的字符[c]::[c]:[c]例如$"%&,{ {1}},/。它所做的工作的是,例如+?!)

根据Wikipedia

  

通常的元字符是{} ^ $。| * +?和。

为什么我的正则表达式适用于某些元字符(因为它们显然被称为),而不是其他元字符?我如何“修复”我的正则表达式以考虑那些不起作用的那些?

1 个答案:

答案 0 :(得分:1)

如何使用它:

(?:\\:|[^:])+:{2}(?:\\:|[^:])+:(?:\\:|[^:])+

Demo(我使用^$个锚来进行演示)


唯一需要解释的部分是“除冒号之外的任何字符(除非前面都有反斜杠)”的逻辑“(?:\\:|[^:])+。让我们打破这一点:

(?:       # start non-capturing group
  \\      # match \ literally
  :       # match : literally
 |        # OR
  [^:]    # match anything but :
)+        # repeat non-capturing group 1+ times

我们一次只能找到一个角色(在非捕捉组中)并重复这个逻辑1次以上。此字符可以是\:,也可以是:[^:])。请注意,\\:必须是您的第一部分,否则[^:]将匹配逃避冒号所需的反斜杠。


更新: 为什么([^(?<!\\):]|\\:)+无效?

简单地说,看起来在字符类中没有做任何事情。所以让我们打破这个:

(             # start capturing group
  [^(?<!\\):] # match anything but (, <, !, \, or :
 |            # OR
  \\          # match \ literally
  :           # match : literally
)+            # repeat capturing group 1+ times