5

次のような文字列を一致させる方法を作成したいと思います

abc(xyz)
abc
abc(xyz)[123]

ここで、各ブラケットはオプションのユニットです。私が持ちたいのは、最適には、次のようなものです

preg_match_all('complicated regex', $mystring, $matches);

以下を$matches返すと:

  • $mystring= abc(xyz)[123]R与える場合$matches=array(0 => "abc", 1=> "xyz", 2=> "123", 3=> "R")
  • $mystring= abc(xyz)R与える場合$matches=array(0 => "abc", 1=> "xyz", 2=> "", 3=> "R")
  • $mystring= abc[123]R与える場合$matches=array(0 => "abc", 1=> "", 2=> "123", 3=> "R")
  • $mystring= abc(xyz)[123]与える場合$matches=array(0 => "abc", 1=> "xyz", 2=> "123", 3=> "")
  • $mystring= abc与える場合$matches=array(0 => "abc", 1=> "", 2=> "", 3=> "")

要点を理解していただければ幸いです。私は次のように試しました:

preg_match_all("/([a-z]*)(\([a-zA-Z]\))?(\[\w\])?/", "foo(dd)[sdfgh]", $matches)

matches[0]は_

Array
(
    [0] => foo
    [1] => 
    [2] => dd
    [3] => 
    [4] => 
    [5] => sdfgh
    [6] => 
    [7] => 
)

追加の空の一致を取得するのはなぜですか? 必要な結果が得られないようにする方法 (inmatchesまたは in matches[0]...)。

4

6 に答える 6

1

試合が 8 回何度も繰り返されるため、非常に多くの結果が得られます。すべての文字列 (空の文字列を含む) は、正規表現の最初の非オプション部分と照合されます: ([a-z]*)

修正された正規表現:

preg_match_all("/^([a-z]*)(\([a-zA-Z]*\))?(\[\w*\])?$/", "foo(ddd)[sdfgh]", $matches); 

編集(件名の2番目の部分の括弧を除外するため)したがって、'ddd'代わりに次のものが必要です'(ddd)'

(?: ... )この正規表現は、サブジェクトのオプションの部分をマークするために「非キャプチャ パターン」を使用しますが、matches 配列ではキャプチャしません。

preg_match_all("/^([a-z]*)(?:\(([a-zA-Z]*)\))?(\[\w*\])?$/", "foo(ddd)[sdfgh]", $matches);

興味深い部分は次のとおり(?:\(([a-zA-Z]*)\))?です。

  • 最初の括弧(?:は、非キャプチャ サブパターンの開始を示します
  • 2 番目の括弧\(は、エスケープされたリテラル括弧です
  • 3 番目の 1 つ(は、標準のキャプチャ サブパターンの開始を示します

$matches 配列には、3 番目の括弧のペアの内容のみが表示されます。

于 2013-05-16T10:32:36.060 に答える
0

なぜpreg_split()を使わないのですか?

$string = 'abc(xyz)[123]';
$array = preg_split('/\]?\(|\)\[?|\[|\]/', $string);
print_r($array);

オンラインデモ

于 2013-05-16T10:35:07.067 に答える