1

文字列を置き換えようとしていますが、最初のオカレンスにしか一致しないようです。別のオカレンスがある場合は何にも一致しないので、何らかの終了区切り文字を追加する必要があると思いますか?

私のコード:

$mappings = array(
    'fname'     => $prospect->forename,
    'lname'     => $prospect->surname,
    'cname'     => $prospect->company,
);

foreach($mappings as $key => $mapping) if(empty($mapping)) $mappings[$key] = '$2';

$match  = '~{(.*)}(.*?){/.*}$~ise';
$source     = 'Hello {fname}Default{/fname} {lname}Last{/lname}';
// $source  = 'Hello {fname}Default{/fname}';

$text = preg_replace($match, '$mappings["$1"]', $source);

したがって、コメントされた$ sourceを使用すると、正常に一致しますが、上記のコードで現在2つの一致があるものを使用すると、何も一致せず、エラーが発生します。

Message: Undefined index: fname}Default{/fname} {lname

Filename: schedule.php(62) : regexp code

それで、私は終了区切り文字か何かを提供する必要があると言っているのは正しいですか?

ありがとう、クリスチャン

4

2 に答える 2

1

どうやらあなたの正規表現fname}Default{/fname} {lnameはの代わりに一致しますDefault

ここで述べたよう{(.*?)}に、の代わりに使用し{(.*)}ます。

{正規表現では特別な意味があるので、エスケープする必要があります\\{

preg_replace_callbackまた、修飾子の代わりに使用することをお勧めしeます(フロー制御と構文の強調表示が強化されており、プログラムに悪意のあるコードを強制的に実行させることはできません)。

あなたが犯している最後の間違いは、要求されたインデックスが存在するかどうかをチェックしていないことです。:)

私の解決策は次のとおりです。

<?php

class A { // Of course with better class name :)
    public $mappings = array(
        'fname' => 'Tested'
    );

    public function callback( $match)
    {
        if( isset( $this->mappings[$match[1]])){
            return $this->mappings[$match[1]];
        }

        return $match[2];
    }   
}

$a = new A();
$match  = '~\\{([^}]+)\\}(.*?)\\{/\\1\\}~is';
$source     = 'Hello {fname}Default{/fname} {lname}Last{/lname}';

echo preg_replace_callback( $match, array($a, 'callback'), $source);

これにより、次のようになります。

[vyktor@grepfruit tmp]$ php stack.php
Hello Tested Last
于 2012-10-10T20:30:29.650 に答える
1

正規表現は文字列の最後に固定されているため、文字列の最後に閉じる{/whatever} 必要があります。また、開始タグと終了タグは単純.*であるため、それらが一致することを確認するものは何もありません。必要なのは、終了タグが開始タグと一致することを確認することです。のような後方参照を使用する{(.+)}(.*?){/\1}と、それらが同じであることを確認できます。

そこには他の落とし穴があると確信しています-作業している文字列の形式を制御できる場合(つまり、独自のテンプレート言語を使用している場合)、よりシンプルで一致しやすいものに移行することを真剣に検討しますフォーマット。デフォルト値を「保存」していないため、タグを囲むと付加価値はありませんが、解析がより複雑になります。を使用$VARNAMEするだけでも同様に機能し、\$[A-Z]+後方参照を使用したり、欲張りでないマッチングを使用していることを明示的に指定したりすることなく、マッチングが容易になります()。

于 2012-10-10T20:51:21.080 に答える