3

拙いタイトルで申し訳ありませんが、非常に一般的な質問です

このパターンに合わせるしかない

;AAAAAAA(BBBBBB,CCCCC,DDDDDD)
  • AAAAA = ";" で始まるすべての文字 "(" に (両方;(含まれていません)
  • BBBBB = "(" から "," までのすべての文字 ((, は含まない)
  • CCCCC = "," から "," までのすべての文字 (両方の ,, は含まれません)
  • DDDDD = "," から ")" までのすべての文字 (両方の ,) は含まれません)

「xとyの間のすべての文字」は、毎回私を殺す問題です

:(

私は PHP を使用しており、このパターン (preg_match_all) のすべての出現に一致する必要があります。これは、悲しいことに、複数の行にまたがる可能性があります。

前もって感謝します!

4

2 に答える 2

3

貪欲な量指定子を使用しないことをお勧めしますが、その代わりに、すべての繰り返しを区切り文字と相互に排他的にすることをお勧めします。これは何を意味するのでしょうか?これは、たとえば、A以外の任意の文字を指定できることを意味します(。この正規表現を与える:

;([^(]*)[(]([^,]*),([^,]*),([^)]*)[)]

最後[)]は必要ありません。

PHP コードは次のようになります。

preg_match_all('/;([^(]*)[(]([^,]*),([^,]*),([^)]*)[)]/', $input, $matches);
$fullMatches = $matches[0];
$arrayOfAs = $matches[1];
$arrayOfBs = $matches[2];
$arrayOfCs = $matches[3];
$arrayOfDs = $matches[4];

コメントが示すように、私のエスケープ テクニックは好みの問題です。もちろん、この正規表現は次と同じです。

;([^(]*)\(([^,]*),([^,]*),([^)]*)\)

しかし、それは他のバリアントよりもはるかにミスマッチ/アンバランスに見えると思います. 選んでください!

最後に、貪欲でない (怠惰な) 量指定子を使用するよりも、このアプローチの方が優れている理由について質問します。ここに、いくつかの良い一般的な読み物があります。基本的に、貪欲でない量指定子を使用すると、エンジンはバックトラックする必要があります。(最初に 1 回の繰り返しを試み、その後一致しないことに気付きます。そのため、繰り返しに戻って別の文字を消費する必要があります。しかし、(それでも一致しないので、もう一度繰り返しに戻ります。ただし、このアプローチでは、エンジンは最初に繰り返しに入るときに、可能な限り多くの電力を消費します。そして、すべての非(文字が消費されると、エンジンは(すぐに次のものを照合できるようになります。

于 2012-11-22T22:05:26.533 に答える
1

次のコードのようなものを使用できます。

preg_match_all('/;(.*?)\((.*?),(.*?),(.*?)\)/s',$text,$matches);

ideone.comでご覧ください。

基本的に、.*?(クエスチョン マークは貪欲ではない) を使用できます。必ず括弧をエスケープしてくださいs。複数の行で機能させるには修飾子が必要になる場合があります。

変数は配列になります。$matches

于 2012-11-22T22:12:56.707 に答える