我正在尝试编写一个简单的正则表达式,用于识别不是列或转义列的字符序列。即:
foo:bar //Does not match
但
foo':bar //Does match
根据我对正则语言的了解,这种语言可以用正则表达式来描述
/([^:]|''[:])*/
您可以在精彩的工具Regexper中看到此表达式的图形表示
使用 php 的preg_match
(基于 PCRE 引擎),这样的表达式与 "foo'':bar" 不匹配。
但是,如果用单个字符替换类:
/([^:]|'':)*/
表达式匹配。
你对此有解释吗?这是PCRE引擎对字符类的一种限制吗?
PS:在正则表达式上测试第一个表达式,即基于 AS3 正则表达式引擎,在更改交替顺序时不提供匹配:
/(''[:]|[^:])*/
它确实匹配,而相同的表达式在 PCRE 中不匹配。
preg_match()
接受正则表达式模式作为字符串,因此您需要对所有内容进行双重转义。
^(?:[^:'''']|'''':)+$
这将匹配一个或多个不是冒号或转义字符的字符[^:'''']
,或者转义冒号'''':
。
为什么你的第一个正则表达式不起作用:/([^:]|''[:])*/
.
这匹配非冒号[^:]
,或者匹配''[:]
匹配文字[
后跟文字:
,然后是文字]
。
为什么这样做:/([^:]|'':)*/
?
这匹配非冒号[^:]
,或者匹配文字'':
,因此它有效地匹配所有内容。
编辑:为什么/([^:]|E[:])*/
不匹配fooE:bar
?
发生这种情况:[^:]
匹配f
然后匹配o
然后匹配另一个o
然后匹配E
,现在它找到一个冒号:
并且无法匹配它,但由于默认情况下 PCRE 引擎不寻找最长的可能匹配,它对到目前为止匹配的内容感到满意并停在那里并返回fooE
作为匹配而不尝试另一种选择E[:]
(顺便说一下,它等于E:
)。
如果要匹配整个序列,则将使用如下所示的表达式:
/([^:E]|E[:])*/
这可以防止[^:]
消耗该E
。
试试这个。这允许安全'':
有机会在否定字符类[^:]
之前。
^(?:'':|[^:])+$
如果您使用交替栏中的值倒置^((?:[^:]|'':)+$
则它不会匹配转义的冒号':
,因为第一个替代项将在第二个表达式有机会尝试之前消耗斜杠 ( '
)。