0

文字列を strtr と同時に置き換えようとしていますが、問題が発生しました。同時に置き換えられる文字が、同時に置き換えられる別の文字の隣にある場合、最初の文字の後の文字は置き換えられません。これを修正するにはどうすればよいですか? ありがとう。

$text = " no bacon cats nobody ";
$text = strtr($text, array(" no " => " bacon ", " bacon " => " no ", " cats " => " dogs "));
echo $text;

予想された結果

bacon no dogs nobody

実績

bacon bacon dogs nobody

PS: これらの単語が別の単語の一部になっていないことを確認する必要があります。それが空白がそこにある理由です。たとえば、「no」という単語は「nobody」の一部であり、文字列内のすべての「no」を置き換えると、「nobody」などの単語も置き換えられます。

4

2 に答える 2

5

それで、ここで何が起こりますか?

$text = " a b c ";
$text = strtr($text, array(" a " => " b ", " b " => " a ", " c " => " d "));

まず、次のことを知っておく必要があります。

  1. 最も長いキーが最初に置き換えられます
  2. 置き換えられた後、このキーを検索しなくなりました

したがって、ここではすべてのキーの長さが同じです。つまり、最初のkey => value要素が置き換えられ、次に 2 番目の要素が置き換えられます。

したがって、最初" a " => " b "に置き換えられ、開始文字列が変更されます。

 a b c 
↑↑↑ Match

これに:

 b b c
↑↑↑ Replacement

値を置き換えた後は、もう検索しないと言ったことを覚えていますか? 丁度!が検索されます" b " => " a "が、文字列のこの部分のみが検索されます。

紀元前_

b の前に検索するスペースがないため、検索されません。そのため、期待した出力が得られません。そしてc、その前にスペースがあるので、再び見つかります。

したがって、ここでのコードの問題は、次のキーの検索に置き換えられた値が含まれていないことです。が文字列に含まれていても[space]b[space]、最初のスペースは key の置換された値からのもの[space]a[space]であり、次の検索には含まれないため、見つかりません。

編集:

あなたの更新された質問から、単語が他の単語の一部になるのを防ぐためにこれを行ったようです。これを解決するには、ルックアップ配列を作成preg_replace_callback()し、単語境界で使用して、その一部だけではなく完全な単語のみに一致させます。

<?php

    $text = " apple bacon cats ";
    $replacement = ["apple" => "bacon", "bacon" => "apple", "cats" => "dogs"];
    $search = array_map(function($v){
        return preg_quote($v, "/");
    }, array_keys($replacement));

    echo $text = preg_replace_callback("/\b(" . implode("|", $search) . ")\b/", function($m)use($replacement){
        return $replacement[$m[1]];
    }, $text);

?>
于 2015-09-04T02:45:00.183 に答える
0

strtr を使用しない方法:

$text = 'no bacon cats nobody';
$rep = ['no'=>'bacon', 'bacon'=>'no', 'cats'=>'dogs'];

$parts = explode(' ', $text);
foreach ($parts as &$part) {
    if (isset($rep[$part]))
        $part = $rep[$part];
}

$result = implode(' ', $parts);

より柔軟なものが必要な場合は、explode行を次のように置き換えます。

$parts = preg_split('~\b~', $parts);

で空の文字列を使用しますimplode

于 2015-09-04T03:28:08.107 に答える