0

コンマで区切られた、(任意の長さの) 英数字の繰り返しグループを見つけるために、preg_match / php スタイルの正規表現を見つけようとしていますか?

したがって、文字列「c、b、a、xz、x、b、a、c、xz、x、x、b、a」がある場合

3 つ以上の値を繰り返す最初の一連の文字を返します。再帰的な後方参照を行う必要があると思います。

<?php
    // lines removed for simplicity
    // test string = "c,b,a,xz,x,b,a,c,xz,x,x,b,a"
    $haystack = "c,b,a,xz,x,b,a,c,xz,x,x,b,a";
    $answer = preg_match('/([A-z]{2,*}[\s]{1})([A-z \s]*)[\1]*/', $haystack );

    echo $answer; // print the first occurrence of the repeating series of two or more
?>

2 つ以上の値の繰り返しシリーズの最初の発生を見つけて、エコー アウトする必要があるだけです。後方参照を再帰的に使用する方法、またはより良い方法はありますか?

編集:コード嘔吐物が削除されました。

4

2 に答える 2

1

'/\b(\w+,\w+),(?:.*,)?\1\b/'動作するはずです。2 つのアイテムの任意のシーケンス、任意の量の他のもの、および同じシーケンスに再び一致します。

キャッチは、正規表現の仕組みにより、最初の重複を持つシーケンスではなく、重複を持つ最初のシーケンスを見つける可能性が高いということです。(最も早く開始された試合が勝ちます。) たとえば、 がある場合は、'a,b,c,d,c,d,a,b,c'おそらく$matches[1]になります。'a,b''c,d'

最初の重複を見つけるには、それを照合し、後読みアサーションでそれを後方参照できる必要があります。それが合法である場合(私はそれが疑わしい)、PHPがそれを可能にする前に幅を固定する必要があります。

編集: しかし、今考えてみると...文字列を逆にしてから使用'/.*\b(\w+,\w+),(?:.*?,)??\1\b/'すると、うまくいくかもしれません。それは、私が言及した制約の周りで踊っています。文字列を逆にすると、複製が元のに来るので、複製を照合して「後で」参照できます。

式の.*先頭の は可能な限りグラブするため、一致は反転された文字列の末尾にできるだけ近い (したがって、元の文字列の先頭にできるだけ近い) ようになります。また、余分な?s は、対応するビットを遅延させるため、必要なだけ一致します。もちろん、逆の文字列で一致を見つけたら、元の文字列で一致するように逆にする必要があります。

そしてもちろん、これは UTF-8 の存在下ですべてを壊す可能性があります。(繰り返しますが、ほとんどの正規表現はそうです。)ただし、ASCII を扱っているだけであれば、動作するはずです。

于 2012-04-20T02:09:46.190 に答える
1


~\b([a-zA-Z0-9]{2,})\b(?=.*\b\1\b)~PHP の専門家ではありませんが、この正規表現を while ループで 使用できると思います。

本文では、結果をハッシュ配列 (php にある場合) で追跡して、
一意のシリーズと位置を出力できます。キャプチャ バッファ 1 には系列があります。

于 2012-04-20T04:34:01.833 に答える