【问题标题】:PHP regex : split on unescaped delimiterPHP 正则表达式:在未转义的分隔符上拆分
【发布时间】:2011-12-09 12:42:02
【问题描述】:

我可以使用以下代码以key:value; 格式拆分字符串:

$inside = "key1:value1;key2:value2;key3:value3;";
preg_match_all("/([^:]+):([^;]+);/s", $inside, $pairs);

我想做的是通过引入转义字符来允许值中出现冒号和分号字符,例如\; 前面紧跟反斜杠的任何冒号或分号都将被忽略。

如果在同一个正则表达式中,则可以将转义字符存储在未转义的匹配数组中,而无需通过str_replace 运行所有内容。感谢您提供的任何帮助。

【问题讨论】:

    标签: php regex escaping


    【解决方案1】:
    preg_match_all(
        '/(                    # Match and capture...
         (?:                   # either:
          \\\\.                # an escaped character
         |                     # or:
          [^\\\\:]             # any character except : or \
         )+                    # one or more times
        )                      # End of capturing group 1
        :                      # Match a colon
        ((?:\\\\.|[^\\\\;])+); # Same for 2nd part with semicolons
        /x', 
        $inside, $pairs);
    

    这样做。但是,它不会删除反斜杠。您不能在正则表达式本身中做到这一点;为此,您需要一个回调函数。

    要匹配最终元素,即使它不以分隔符结尾,请将 ; 更改为 (?:;|$): 相同)。并返回空元素以及将+ 更改为*

    【讨论】:

    • 谢谢蒂姆。这很好用。您认为删除匹配数组中任何转义字符的最有效方法是什么?
    • 请注意,如果字符串不以分隔符结尾,则不会找到最后一个元素。我已经编辑了答案以包括如何做到这一点。
    【解决方案2】:

    你可以这样做:

    $inside = "key\:1:value\;1;key2:value2;key3:value3;";
    $pairs = preg_split('/(?<!\\\\);/',$inside,-1,PREG_SPLIT_NO_EMPTY );
    foreach($pairs as $pair) {
            list($k,$v) = preg_split('/(?<!\\\\):/',$pair);
            // $k and $v have the key and value respectively.
    }
    

    See it

    【讨论】:

    • 这一直有效,直到您在字符串中找到转义的反斜杠:key1\\:value1\\; 等。可能不是问题,但谁知道呢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-29
    • 2020-10-26
    • 1970-01-01
    • 2013-07-06
    • 1970-01-01
    相关资源
    最近更新 更多