我有一些正则表达式我遍历整个HTML页面寻找字符串并替换它们,但是如果字符串是单引号或双引号我不希望它匹配。
当前正则表达式:([a-zA-Z_][a-zA-Z0-9_]*)
我想匹配steve
,john
,cathie
和john likes to walk
(x3)
但不是"steve"
,'sophie'
或"john"'likes'"cake"
我试过(^")([a-zA-Z_][a-zA-Z0-9_]*)(^")
但没有匹配?
测试案例:
(steve=="john") would return steve
("test"=="test") would not return anything
(boob==lol==cake) would return all three
答案 0 :(得分:3)
试试这个:
(\b(?<!['"])[a-zA-Z_][a-zA-Z_0-9]*\b(?!['"]))
反对这个字符串:
john "michael" michael 'michael elt0n_john 'elt0n_j0hn' 1 2 3 4 5 6
它将匹配nr 1 john
,nr 3 Michael
和nr 5 elt0n_john
答案 1 :(得分:2)
您可以尝试:
preg_match_all('#(?<!["\']) \b \w+ \b (?!["\'])#x', $str, $matches);
\w+
匹配单词字符,但允许0123sophie
。 \b
匹配字边界,从而确保反引用断言不会过早终止。
然而,这个正则表达式也无法找到只有一个单引号“之前或之后”的单词。
答案 2 :(得分:1)
要做到这一点,你可能需要一些黑魔法:
'~(?:"[^"\\\\]*+(?:\\\\.[^"\\\\]*+)*+"|\'[^\'\\\\]*+(?:\\\\.[^\'\\\\]*+)*+\')(*SKIP)(*F)|([a-zA-Z_][a-zA-Z0-9_]*)~'
(?:"[^"\\\\]*+(?:\\\\.[^"\\\\]*+)*+"|\'[^\'\\\\]*+(?:\\\\.[^\'\\\\]*+)*+\')
部分匹配单引号或双引号中的字符串,并实现反斜杠转义。 (*SKIP)(*F)
跳过引用的字符串并强制失败。 ([a-zA-Z_][a-zA-Z0-9_]*)
是你的正则表达式。
PS:如果您在PHP脚本上使用此功能,则可能需要使用Tokenizer。这样你就可以排除关键字(例如class
或abstract
,我不知道你是否需要这个),你可以更好地处理边缘情况(比如HEREDOC)。
答案 3 :(得分:1)
如果john
位于不完整的引号中,则无法与"john
匹配,例如john"
,'john
,john'
和john's birthday
(可以是(?:'[^'\n]*'|"[^"\n]*")(*SKIP)(*F)|\b[a-zA-Z_][a-zA-Z_0-9]*\b
与{{1}}等同时发生。请参阅this demo。
此替代解决方案只是跳过引号中的任何内容:
{{1}}
请参阅demo
无论哪种方式,使用引号,没有解决方案是完美的,因为你总是冒着不平衡报价的风险。在这种情况下,我试图通过假设如果它在另一条线上,它是一个不同的字符串来缓解这个问题。
参考
答案 4 :(得分:0)
好的我觉得我有它,它适用于你的测试用例:
(?<!"|'|\w)(\w+)(?!"|'|\w)
完成前瞻/后视正则表达式功能。