免责声明:我不认为这是重复的什么'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