0

我有另一个与我上一个问题preg_split非常相似的php问题,尽管我担心解决方案会更加复杂。和以前一样,我正在尝试使用 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 = "/('(?:(?!\\').*)')|(\"(?:(?!\\'|').*)\")/";

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

4

1 回答 1

1

试试这个:

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

在http://rubular.com/r/Eps2mx8KCw进行演示。

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

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

在http://rubular.com/r/NLZKyr9xLk进行演示。

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

于 2012-09-11T05:58:35.553 回答