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

发布于 2025-01-06 22:01:51 字数 1036 浏览 0 评论 0原文

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

输入:

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'

您能给我建议如何跳过整个不需要的块(“blah blah blah”)而不是只跳过第一个引用吗?

I want to escape matching quotes except those in tag properties, for example:

input:

xyz <test foo='123 abc' bar="def 456"> f00 'escape me' b4r "me too" but not this </tEsT> blah 'escape " me'

expected output:

xyz <test foo='123 abc' bar="def 456"> f00 \'escape me\' b4r \"me too\" but not this </tEsT> blah \'escape " me\'

I have following regexp:

$result = preg_replace('/(([\'"])((\\\2|.)*?)\2)/', "\\\\$2$3\\\\$2", $input);

which returns:

xyz <test foo=\'123 abc\' bar=\"def 456\"> f00 \'escape me\' b4r \"me too\" but not this </tEsT> blah \'escape " me\'

now I would like to use regexp zero-width negative look behind to skip matching quotes that have equal sign in front:

$result = preg_replace('/((?<=[^=])([\'"])((\\\2|.)*?)\2)/', "\\\\$2$3\\\\$2", $input);

but the result is still not as expected:

xyz <test foo='123 abc\' bar="def 456"> f00 \'escape me\' b4r "me too" but not this </tEsT> blah \'escape " me'

Can you please give me advice how I can skip whole unwanted block (="blah blah blah") instead of skipping just first quote?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

£冰雨忧蓝° 2025-01-13 22:01:51

不要向后看来建立背景,而要向前看。通常会容易得多。

$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

我假设属性值中不会有任何尖括号。

Instead of looking backward to establish the context, look forward. It's usually much easier.

$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

I'm assuming there won't be any angle brackets in the attribute values.

带上头具痛哭 2025-01-13 22:01:51

这是另一张。

$str = "xyz <test foo='123 abc' bar=\"def 456\"> f00 'escape me' b4r \"me too\" but not this <br/> <br/></tEsT> blah 'escape \" me'";

$str_escaped = preg_replace_callback('/(?<!\<)[^<>]+(?![^<]*\>)/','escape_quotes',$str);
// check all the strings outside every possible tag
// and replace each by the return value of the function below

function escape_quotes($str) {
    if (is_array($str)) $str = $str[0];
    return preg_replace('/(?<!\\\)(\'|")/','\\\$1',$str);
    // escape all the non-escaped single and double quotes
    // and return the escaped block
}

Here's another one.

$str = "xyz <test foo='123 abc' bar=\"def 456\"> f00 'escape me' b4r \"me too\" but not this <br/> <br/></tEsT> blah 'escape \" me'";

$str_escaped = preg_replace_callback('/(?<!\<)[^<>]+(?![^<]*\>)/','escape_quotes',$str);
// check all the strings outside every possible tag
// and replace each by the return value of the function below

function escape_quotes($str) {
    if (is_array($str)) $str = $str[0];
    return preg_replace('/(?<!\\\)(\'|")/','\\\$1',$str);
    // escape all the non-escaped single and double quotes
    // and return the escaped block
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文