4

PCRE 正規表現で、文字の出現回数 (n) をカウントし、別の文字 (具体的には{and }) の n 回の出現を検出した後に検索を停止する方法はありますか。

これは、コード ブロックを取得するためです (内部にコード ブロックがネストされている場合とない場合があります)。

単純化すると、入力は 1 行の文字列になり、中括弧以外の文字は数字、コロン、コンマのみになります。コード ブロックの抽出を試みる前に、入力が次の基準を満たしている必要があります。

$regex = '%^(\\d|\\:|\\{|\\}|,)*$%';

すべてのブレースには一致するペアがあり、正しくネストされます。

文字列内のすべての文字をチェックし、中かっこの出現ごとにカウントするスクリプトを書き始める前に、これが達成できるかどうかを知りたいです。これらの文字列のサイズは数キロバイトになる可能性があるため、正規表現ははるかにメモリに優しくなります。

ありがとう、ムニズ。

解決

PCRE: 同時に怠け者で貪欲 (所有量指定子)

4

4 に答える 4

4

これは、まさに正規表現が適していないことです。典型的な例です。

文字列を 1 文字ずつ反復処理し、ネスト レベルのカウントを保持する必要があります。

于 2010-02-27T19:08:31.960 に答える
4

pcre には再帰パターンがあるため、次のようなことができます

$code_is_valid = preg_match('~^({ ( (?>[^{}]+) | (?1) )* })$~x', '{' . $code .'}');

もう1つは、特に大きな文字列の場合、これが単純なカウンターよりも高速またはメモリ消費量が少ないとは思わない.

これは、文字列内のすべての(有効な)コードブロックを見つける方法です

preg_match_all('~ { ( (?>[^{}]+) | (?R) )* } ~x', $input, $blocks);
print_r($blocks);
于 2010-02-27T19:30:05.530 に答える
0
$regex='%^(\\d|\\:|\\{|\\}|,){0,25)$%';
preg_match($regex,$target,$matches);

ここで、最初の行の 25 は、最大発生回数を示します。次に確認します。

$n=count($matches);
于 2010-02-27T19:08:43.707 に答える
0

あなたが記述している言語は通常の言語ではないため、それは不可能です。

代わりにパーサーを使用してください。

于 2010-02-27T19:08:47.680 に答える