【问题标题】:Regex to escape double quotes inside double quotes with preg_replace正则表达式用 preg_replace 转义双引号内的双引号
【发布时间】:2012-09-05 22:55:23
【问题描述】:

我整天都在试图逃避双引号内的所有双引号(是的,疯了),我终于放弃了。我有这样的数据:

{ "test": "testing with "data" like this", "subject": "trying the "special" chars" }

我一直在尝试将每个 " 替换为 \" 在类似这样的 /"(.*)+, "/ 内,这意味着双引号内的所有内容,后跟逗号和空格。

我需要一种方法来解决这个问题:

{ "test": "testing with "data" like this", "subject": "trying the "special" chars" }

进入这个:

{ "test": "testing with \"data\" like this", "subject": "trying the \"special\" chars" }

使用 preg_replace。

【问题讨论】:

    标签: php


    【解决方案1】:

    查看您的正则表达式,我建议您阅读regex greediness. 如果您选择引号到第一个逗号之间的所有内容,您会遇到问题。返回的第一件事是test": "testing with "data" like this,因此如果您将所有" 替换为\",您将拥有test\": \"testing with \"data\" like this,这显然不是您想要的。我建议使用这样的东西:

    /"((?:.|\n)*?)"\s*[:,}]\s*/
    

    说明

    • "((?:.|\n)*?)" - 捕获两个引号之间的任何字符;模式仍然为真时的最小数量
    • \s* - 匹配 0 个或多个空白字符
    • [:,}] - 匹配冒号、逗号或右括号字符
    • \s* - 匹配 0 个或多个空白字符

    使用此正则表达式和您的数据,返回的第一件事是test。下一个返回的是testing with "data" like this,所以替换后你会得到testing with \"data\" like this


    更新
    $test = '{ "test": "testing with "data" like this", "subject": "trying the "special" chars" }';
    $pattern = '/"((?:.|\n)*?)"\s*[:,}]\s*/';
    preg_match_all($pattern, $test, $matches);
    foreach($matches[1] as $match){
        $answers[] = str_replace('"','\\"',$match);
    }
    print_r($answers);
    // Outputs
    // Array ( [0] => test [1] => testing with \"data\" like this [2] => subject [3] => trying the \"special\" chars )
    


    更新 2

    我认为使用preg_match_all 然后str_replace 是解决问题的更好方法,因为该正则表达式更加稳定。但是如果你坚持使用preg_replace那么你可以使用这个代码:

    $string = '{ "test": "testing with "data" like this", "subject": "trying the "special" chars" }';
    $pattern = '/(?<!:|: )"(?=[^"]*?"(( [^:])|([,}])))/';
    $string = preg_replace($pattern, '\\"', $string);
    print_r($string);
    //Outputs
    //{ "test": "testing with \"data\" like this", "subject": "trying the \"special\" chars" }
    

    说明

    • (?&lt;! - 开始消极的向后看
    • :|: ) - 匹配冒号或带有空格的冒号并结束后视
    • " - 匹配引用
    • (?= - 开始积极的前瞻
    • [^"]*? - 匹配除引号之外的任何内容;模式仍然为真时的最小数量
    • "(( [^:])|([,}])) - 匹配引号后跟空格和冒号以外的任何内容,或者匹配引号后跟逗号或右括号
    • ) - 结束前瞻

    你可以read more about regex lookaheads here. 我认为这个正则表达式很乱,虽然从技术上讲它是有效的。我打算继续玩它以使其变得更好,但我累了,所以我现在要睡觉了。此正则表达式允许您的数据更松散地键入。这两种方法以及它们的任意组合都有效:

    { "test" : "testing with "data" like this" , "subject" : "trying the "special" chars" }
    {"test":"testing with "data" like this","subject":"trying the "special" chars"}
    

    【讨论】:

    • 转义字符如 \n 和 \t 可以出现在引号之间。
    • 有没有办法只选择以 , 或 } 结尾的双引号之间的引号?像这样:/: "(["]*)" [,}]/
    • 不过,这并不能帮助我隔离其他双引号内的双引号。我想隔离它们,以便我可以替换为 \"
    • @vinnylinux - 我更新了我的帖子,以便您了解它将如何帮助您解决问题。并且正则表达式现在接受任何字符。
    • 惊人的、详细的、具有指导意义的答案...谢谢!
    猜你喜欢
    • 2013-05-10
    • 2011-05-01
    • 1970-01-01
    • 2013-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多