3

を使用してpreg_replace_callback、1つの後方参照のみを置き換えることは可能ですか?それとも、全部を返却する必要がありますか?

トークンのデフォルト値を引用符で囲んでいます。

$str = 'This is a {$token|token was empty}';
$str = preg_replace_callback('~{\$\w+\|(.*)?}~i', function($match) {
    //$match[1] is "token was empty"
    //I want to just replace $match[1], but it needs me to return the whole thing
}, $str);

トークンの新しいバージョンを作成して返すことができるように、より多くの後方参照を取得する必要がありますか?後方参照1を置き換えることはできませんか?ありがとう。

4

3 に答える 3

4

トークンの新しいバージョンを構築してそれを返すことができるように、より多くの後方参照を取得する必要がありますか?後方参照 1 を単に置き換えることはできませんか?

次の 2 つのオプションがあります。

  1. あなたが言ったように、追加の後方参照を使用して置換文字列を作成するか、または
  2. ルックアラウンドを使用して、置換するパーツのみを一致させます。

2 番目の方法は少し効率が悪く、場合によっては (先読みと後読みが重複する可能性がある場合) 無効な一致につながる可能性があるため、通常は最初の方法を使用することをお勧めします。この場合は問題ありません。

2 番目のオプションの例は次のようになります。

preg_replace_callback('~{\$\w+\|\K(?:[^{}]+)?(?=})~i', function($match){
    // $match[0] contains what used to be the first capturing group.
    // return the value you want to replace it with
    // (you can still use the capturing group if you want, but it's unnecessary)
});
  • \Kそれより前のすべてを実際の一致から除外する方法です (可変長の後読みがある場合のように)。
  • (?=})は先読みであり、以下は a である}必要がありますが、一致自体には含まれていません。
于 2012-08-14T22:08:14.477 に答える
2

代わりに、次のような正規表現を使用する必要があります。

~\{\$(\w+?)(?:\|(.+?))?\}~i

次に、コールバックに何が渡されているかを簡単に確認できます。

$str = 'This is a {$token|token was empty}';
$str = preg_replace_callback('~\{\$(\w+?)(?:\|(.+?))?\}~i', function($match) {
    var_dump($match);
    exit;
}, $str);

出力:

array(3) {
  [0]=>
  string(24) "{$token|token was empty}"
  [1]=>
  string(5) "token"
  [2]=>
  string(15) "token was empty"
}

そこから、が設定されているかどうかを確認できます。$match[1]設定されている場合はその値を返し、そうでない場合は次を返し$match[2]ます。

$foo = 'foo';
$str = 'Foo: {$foo|not set}, Bar: {$bar|not set}';
$str = preg_replace_callback('~\{\$(\w+?)(?:\|(.+?))?\}~i', function($match) {
    if (isset($GLOBALS[$match[1]])) {
        return $GLOBALS[$match[1]];
    } else {
        return $match[2];
    }
}, $str);
var_dump($str);

出力:

string(22) "Foo: foo, Bar: not set"

注:$GLOBALSここでは、デモンストレーションのみを目的として使用しています。可能であれば、PHP 5.4 のクロージャ バインディングを使用することをお勧めします。これにより、クロージャに特定のオブジェクトをコンテキストとして割り当てることができます (たとえば、テンプレート/ビュー オブジェクト、または置換しようとしている変数を含むもの)。 . PHP 5.4 を使用していない場合は、構文function($match) use ($obj)where is your context を使用して、代わりにクロージャー内$objをチェックすることもできます。isset($obj->{$match[1]})

于 2012-08-14T21:17:19.397 に答える
0

私は最近、これを行うためのより簡単な方法を思いつきました。例えば; \w+\d+\w+一致させて数字のみを変更したい場合。

$value = preg_replace_callback('~(\w+)(\d+)(\w+)~', function($match) {
    $match[2] = $match[2] * 2;//Do whatever I want to $match[2]
    return $match[1] . $match[2] . $match[3];
}, $value);

非常にきれいな!

于 2012-12-20T20:54:47.227 に答える