2

文字列に含まれる可能性のあるいくつかの単語の最初と最後の文字を一致させようとしていました。で正規表現を使用していました|

次の文字列を見てみましょう。

The quick brown fox jumps over the lazy dog

foxまたはのどちらかに一致させたいdogので、次の正規表現を作成しました。

/fox|dog/

PHPを使用するpreg_replaceと、その正規表現は正しく機能します。

$str = 'The quick brown fox jumps over the lazy dog';
echo preg_replace('/fox|dog/', '=>$0<=', $str);

これはエコーします:

The quick brown =>fox<= jumps over the lazy =>dog<=

それは私が望む結果ではありません。そのため、その正規表現から始めて、結果が次のようになるように変更しようとしました。

The quick brown =>f...x<= jumps over the lazy =>d...g<=

私はこのコードで試しました:

$str = 'The quick brown fox jumps over the lazy dog';
echo preg_replace('/(f)o(x)|(d)o(g)/', '=>$1...$2<=', $str);

これは私が望むものを生み出しませんでした。これはエコーしました:

The quick brown =>f...x<= jumps over the lazy =>...<=

いくつかのデバッグの後、私はその理由を理解しました。私が使っ|ていたので、それは各単語に別々に一致するだろうと思いましたが、そうではありません。私が思ったように、は逆参照ですが、そうfではありません。これは実際には後方参照です!これは、グループが、のどちら側が一致するかだけでなく、正規表現全体を対象としているためです。ただし、後方参照は常に一致する(または)という単語であるため、少し混乱しています。1dd3|0foxdog

逆参照を使用して、複数の単語の最初と最後の文字を一致させるにはどうすればよいですか?

を使用して解決策を見つけましたpreg_replace_callbackが、後方参照を使用してこれと同じ結果を得ることができるかどうか疑問に思いました。

$str = 'The quick brown fox jumps over the lazy dog';
echo preg_replace_callback('/fox|dog/', function($matches){
    $a = $matches[0];
    return '=>'.$a[0].'...'.$a[strlen($a)-1].'<=';
}, $str);
4

2 に答える 2

2

実際には、コールバック関数メソッドは、すべてのケースで機能するため、これらすべてよりも優れています。試合の長さに応じて、多かれ少なかれキャラクターを表示することもできます.


以下は私の最初の答えです。これは、上で説明したものよりも劣っています

一般に、次のように実行できます。

/(?=(.))(?:pattern)(?<=(.))/s

patternあなたのパターンで埋めてください。sフラグを使用して、.例外なくすべての文字に真に一致するようにしました。元のパターンが最高レベルにない場合は、非キャプチャ グループpattern内にある必要はありません。|

ただし、置換を行う前に、パターンによってキャプチャされたテキストの長さを確認する必要があります。(特に、長さが 1 の場合、場合によっては 2 の場合もあります)。これは、replace コールバック関数を使用して簡単に実現できます。

ただし、上記の方法は、最小長が 0 のパターンではうまく機能しない可能性があることに注意してください。

于 2013-01-30T18:41:48.557 に答える
2

これには、一致しない先読み式を利用できます。

/(?=fox|dog)(f|d)o(x|g)/

(PHP ではテストしていませんが、JS では動作します)

最初に、次が検索された単語の 1 つであるかどうかをテストし、次に 1 つのキャプチャ グループのみの最初と最後の文字に一致します。ただし、単語がそれほど似ていない場合 (ここでは、同じ長さ、同じ中間文字 [s])、この方法ははるかに複雑になります。

于 2013-01-30T18:35:38.427 に答える