php - 转义除标签属性之外的匹配引号

标签 php regex escaping

我想转义除标记属性中的匹配引号,例如:

输入:

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/

相关文章:

java - 将Java字符串转义为utf-8

javascript - 使用 JS - jQuery,如何取消转义 html 并将 `quotes & <>` 放回字符串中?

php - 使用 whois 检查子域名

c# - 正则表达式匹配一组字母数字后跟一组空格,使字符总数固定

ruby - 解析 Ruby 时查找数字模式

javascript - 正则表达式 - 将字符串转换为驼峰大写字母 `dot`

PHP 对象在变量名中有分号(或其他奇怪的字符)

javascript - 如何在动态加载的 HTML 中执行 Javascript

php- 如何去除文本中的 CSS

php - Laravel 命令总线,何时使用自处理命令?