我正在尝试编写一个简单的正则表达式,它可以识别不是列或转义列的字符序列。 即:
foo:bar //Does not match
但
foo\:bar //Does match
根据我对常规语言的了解,这种语言可以用正则表达式来描述
/([^:]|\\[:])*/
您可以在精彩工具Regexper
中看到此表达式的图形表示使用php的preg_match
(基于PCRE引擎),这样的表达式与“foo \:bar”不匹配。
但是,如果用单个char替换该类:
/([^:]|\\:)*/
表达式匹配。
你对此有解释吗?这是对字符类的PCRE引擎的限制吗?
PS:在基于AS3 Regexp引擎的RegExr上测试第一个表达式,在改变交替顺序时不提供匹配:
/(\\[:]|[^:])*/
它匹配,而PCRE中的相同表达式不匹配。
答案 0 :(得分:1)
你可以试试这个。这允许secuence \\:
在否定的角色类[^:]
之前有机会。
^(?:\\:|[^:])+$
如果您使用交替栏中的值,如^((?:[^:]|\\:)+$
中那样,它将与转义冒号\:
不匹配,因为第一个选项将在第二个表达式之前使用斜杠(\
)有机会尝试。
答案 1 :(得分:1)
preg_match()
接受正则表达式模式作为字符串,因此您需要双重转义所有内容。
^(?:[^:\\\\]|\\\\:)+$
匹配一个或多个非冒号或转义字符[^:\\\\]
或转义冒号\\\\:
的字符。
为什么你的第一个正则表达式不起作用:/([^:]|\\[:])*/
。
这匹配非冒号[^:]
,或者匹配\\[:]
,其匹配文字[
,后跟文字:
,然后是文字]
为什么会这样:/([^:]|\\:)*/
?
这与非冒号[^:]
匹配,或者与文字\\:
匹配,因此它可以有效地匹配所有内容。
修改:为什么/([^:]|E[:])*/
与fooE:bar
不匹配?
会发生这种情况:[^:]
与f
匹配,然后匹配o
,然后匹配o
,然后匹配E
,现在它找到了冒号:
并且它不匹配,但是因为默认情况下PCRE引擎不会查找最长匹配,它对目前已匹配的内容感到满意并且在那里停止并返回{{1}在没有尝试其他替代fooE
的情况下(完全相同于E[:]
)。
如果你想匹配整个序列,那么你将使用像这样的表达式:
E:
这可以防止/([^:E]|E[:])*/
使用[^:]
。