【问题标题】:string to array, split by single and double quotes, ignoring escaped quotes字符串到数组,由单引号和双引号分隔,忽略转义引号
【发布时间】:2012-09-11 13:58:35
【问题描述】:

我有另一个与my last question 非常相似的php preg_split 问题,尽管我担心解决方案会相当复杂。和以前一样,我正在尝试使用 php 将字符串拆分为数组组件,使用 " 或 ' 作为分隔符。但是除此之外,我想忽略字符串中的转义单引号(字符串中的转义双引号将不会发生,因此无需担心)。我上一个问题中的所有示例仍然有效,但此外还应该获得以下两个期望的结果:

$pattern = "?????";
$str = "the 'cat\'s dad sat on' the mat then \"fell 'sideways' off\" the mat";
$res = preg_split($pattern, $str, null, PREG_SPLIT_DELIM_CAPTURE);
print_r($res);
/*output:
Array
(
    [0] => the 
    [1] => 'cat\'s dad sat on'
    [2] =>  the mat then
    [3] => "fell 'sideways' off"
    [4] =>  the mat
)*/

$str = "the \"cat\'s dad\" sat on 'the \"cat\'s\" own' mat";
$res = preg_split($pattern, $str, null, PREG_SPLIT_DELIM_CAPTURE);
print_r($res);
/*output:
Array
(
    [0] => the 
    [1] => "cat\'s dad" 
    [2] =>  sat on
    [3] => 'the "cat\'s" own'
    [4] =>  mat
)*/

如果没有转义引号,@mcrumley 对我上一个问题的回答效果很好:

$pattern = "/('[^']*'|\"[^\"]*\")/U";

但是,只要给出一个转义的单引号,正则表达式就会使用它作为匹配的结尾,这不是我想要的。

我尝试过这样的事情:

$pattern = "/('(?<=(?!\\').*)'|\"(?<=(?!\\').*)\")/";

但它不起作用。不幸的是,我对环视的知识还不够好。

经过一番阅读和摆弄......

这似乎更接近:

$pattern = "/('(?:(?!\\').*)')|(\"(?:(?!\\'|').*)\")/";

但是贪心程度是错误的,不会产生上述输出。

【问题讨论】:

    标签: php regex preg-split


    【解决方案1】:

    试试这个:

    $pattern = "/(?<!\\\\)('(?:\\\\'|[^'])*'|\"(?:\\\\\"|[^\"])*\")/";
                 ^^^^^^^^^  ^^^^^^^^^    ^     ^^^^^^^^^^     ^
    

    http://rubular.com/r/Eps2mx8KCw 上的演示。

    您也可以使用反向引用将其折叠成一个统一的表达式:

    $pattern = "/(?<!\\\\)((['\"])(?:\\\\\\2|(?!\\2).)*\\2)/";
    

    http://rubular.com/r/NLZKyr9xLk 上的演示。

    如果您还希望在文本中识别转义的反斜杠,这些方法不起作用,但我怀疑这是您需要考虑的情况。

    【讨论】:

    • +1 天才!你知道哪一个跑得更快,还是一样的速度?
    • 嗯,如果我不得不猜测的话,第一个会更快,因为第二个需要存储和引用这种引用。第二个仅仅是美学上的改进(在我看来)。
    猜你喜欢
    • 2012-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    相关资源
    最近更新 更多