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



免责声明:我不认为这是重复的什么's正则表达式匹配任何东西,除了双引号前没有反斜杠?

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

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

我不擅长regex,但我检查了的负面影响,并提出了(不是Java,而是常规的regex):

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

类似

(1) asd::asd:asd

但是不匹配,例如

(2) asd:asd::asd:asd:ads:asd(然而,这应该)。

对于上述问题的公认答案,我还尝试了以下问题。

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

这适用于(2),以及一些但不是所有的特殊字符(根据RegexPlanet)。当在[c]::[c]:[c]的组合中使用时,字符[c]确实有效,例如$, ", %, &, /, +工作的是,例如,?, !, ),

根据维基百科

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

为什么我的regex工作的一些元字符(因为他们显然被称为),而不是其他的?我如何"修复"我的正则表达式,以考虑到那些不工作?

如何使用:

(?:\:|[^:])+:{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

最新更新