我想转义除标记属性中的匹配引号,例如:
输入:
xyz <test foo='123 abc' bar="def 456"> f00 'escape me' b4r "me too" but not this </tEsT> blah 'escape " me'
预期输出:
xyz <test foo='123 abc' bar="def 456"> f00 \'escape me\' b4r \"me too\" but not this </tEsT> blah \'escape " me\'
我有以下正则表达式:
$result = preg_replace('/(([\'"])((\\\2|.)*?)\2)/', "\\\\$2$3\\\\$2", $input);
返回:
xyz <test foo=\'123 abc\' bar=\"def 456\"> f00 \'escape me\' b4r \"me too\" but not this </tEsT> blah \'escape " me\'
现在我想使用正则表达式零宽度负向后看来跳过前面有等号的匹配引号:
$result = preg_replace('/((?<=[^=])([\'"])((\\\2|.)*?)\2)/', "\\\\$2$3\\\\$2", $input);
但结果还是不如预期:
xyz <test foo='123 abc\' bar="def 456"> f00 \'escape me\' b4r "me too" but not this </tEsT> blah \'escape " me'
能否请您给我一些建议,如何跳过整个不需要的 block (="blah blah blah") 而不是只跳过第一个引号?
最佳答案
与其向后看以建立上下文,不如向前看。这通常要容易得多。
$result = preg_replace('/([\'"])(?![^<>]*>)((?:(?!\1).)*)\1/',
'\\\\$1$2\\\\$1',
$subject);
(['"]) # capture the open quote
(?![^<>]*>) # make sure it's not inside a tag
( # capture everything up to the next quote
(?: # ...after testing each character to
(?!\1|[<>]). # ...to be sure it's not the opening quote
)* # ...or an angle bracket
)
\1 # match another quote of the same type as the first one
我假设属性值中不会有任何尖括号。
关于php - 转义除标签属性之外的匹配引号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9326719/