0

最後の質問preg_splitと非常によく似た別のphpの質問がありますが、解決策がかなり複雑になるのではないかと心配しています。前と同じように、区切り文字として " または ' を使用して、php を使用して文字列を配列コンポーネントに分割しようとしています。ただし、これに加えて、文字列内のエスケープされた単一引用符を無視したいと思います (文字列内のエスケープされた二重引用符は私の最後の質問の例はすべて有効なままですが、さらに次の 2 つの望ましい結果も得られるはずです。

$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 に答える