3

"または'を区切り文字として使用して、php を使用して文字列を配列コンポーネントに分割しようとしています。一番外側の文字列で分割したいだけです。以下に 4 つの例と、それぞれの望ましい結果を示します。

$pattern = "?????";
$str = "the cat 'sat on' the mat";
$res = preg_split($pattern, $str);
print_r($res);
/*output:
Array
(
    [0] => the cat 
    [1] => 'sat on'
    [2] =>  the mat
)*/

$str = "the cat \"sat on\" the mat";
$res = preg_split($pattern, $str);
print_r($res);
/*output:
Array
(
    [0] => the cat 
    [1] => "sat on"
    [2] =>  the mat
)*/

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

$str = "the 'cat \"sat\" on' the mat 'when \"it\" was' seventeen";
$res = preg_split($pattern, $str);
print_r($res);
/*output:
Array
(
    [0] => the
    [1] => 'cat "sat" on'
    [2] =>  the mat
    [3] => 'when "it" was'
    [4] =>  seventeen
)*/

ご覧のとおり、最も外側の引用で分割したいだけで、引用内の引用は無視したいのです。

私が思いついた最も近いの$pattern

$pattern = "/((?P<quot>['\"])[^(?P=quot)]*?(?P=quot))/";

しかし、明らかにこれは機能していません。

4

4 に答える 4

2

preg_splitオプションで使用できPREG_SPLIT_DELIM_CAPTUREます。正規表現は、必要なキャプチャグループが結果を台無しにするため、@JanTuroňのバックリファレンスアプローチほどエレガントではありません。

$str = "the 'cat \"sat\" on' the mat the \"cat 'sat' on\" the mat";
$match = preg_split("/('[^']*'|\"[^\"]*\")/U", $str, null, PREG_SPLIT_DELIM_CAPTURE);
print_r($match);
于 2012-09-10T15:26:08.857 に答える
1

これだけpreg_matchに使用できます:

$str = "the \"cat 'sat' on\" the mat";
$pattern = '/^([^\'"]*)(([\'"]).*\3)(.*)$/';

if (preg_match($pattern, $str, $matches)) {
  printf("[initial] => %s\n[quoted] => %s\n[end] => %s\n",
     $matches[1],
     $matches[2],
     $matches[4]
  );
}

これは以下を出力します:

[initial] => the 
[quoted] => "cat 'sat' on"
[end] =>  the mat

正規表現の説明は次のとおりです。

  • /^([^\'"]*)=>最初のキャプチャされたグループの最初の引用符(一重または二重のいずれか)まで初期ビットを置きます
  • (([\'"]).*\3)=> 最初の引用符 (一重引用符または二重引用符のいずれか) (\3 でキャプチャーされる) から終了引用符 (開始引用符と同じタイプである必要があるため、\3) までに対応するテキストを \2 でキャプチャーします。正規表現が本質的に貪欲であるという事実は、内部にいくつの引用符が含まれているかに関係なく、最初の引用符から最後の引用符まで取得するのに役立ちます。
  • (.*)$/=> \4 で最後までキャプチャ
于 2012-09-10T15:27:39.000 に答える
1

preg_replace_callbackを使用したさらに別のソリューション

$result1 = array();
function parser($p) {
  global $result1;
  $result1[] = $p[0];
  return "|"; // temporary delimiter
}

$str = "the 'cat \"sat\" on' the mat 'when \"it\" was' seventeen";
$str = preg_replace_callback("/(['\"]).*\\1/U", "parser", $str);
$result2 = explode("|",$str); // using temporary delimiter

これで、これらの配列を次を使用して圧縮できますarray_map

$result = array();
function zipper($a,$b) {
  global $result;
  if($a) $result[] = $a;
  if($b) $result[] = $b;
}
array_map("zipper",$result2,$result1);
print_r($result);

そして結果は

[0] => the 
[1] => 'cat "sat" on'
[2] =>  the mat 
[3] => 'when "it" was'
[4] =>  seventeen

注:この偉業を行うクラスを作成した方がよいので、グローバル変数を避けることができます。

于 2012-09-10T15:33:14.613 に答える