Php 用strtr同时替换字母

Php 用strtr同时替换字母,php,regex,replace,preg-replace,strtr,Php,Regex,Replace,Preg Replace,Strtr,我试图用strtr同时替换字符串,但遇到了一个问题。如果同时替换的字母与另一个同时替换的字母相邻,则不会替换第一个字母后的字母。我能做些什么来解决这个问题?谢谢 $text = " no bacon cats nobody "; $text = strtr($text, array(" no " => " bacon ", " bacon " => " no ", " cats " => " dogs ")); echo $text; 预期结果 实际结果 附言:我必须确保这些

我试图用strtr同时替换字符串,但遇到了一个问题。如果同时替换的字母与另一个同时替换的字母相邻,则不会替换第一个字母后的字母。我能做些什么来解决这个问题?谢谢

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

实际结果

附言:我必须确保这些词不是另一个词的一部分。这就是为什么会有空白。例如,单词“no”是“nobody”的一部分,如果替换字符串中的所有“no”,它也将替换类似“nobody”的单词

那么这里发生了什么

$text = " a b c ";
$text = strtr($text, array(" a " => " b ", " b " => " a ", " c " => " d "));
首先,你必须知道:

  • 最长的钥匙将首先更换
  • 被替换后,它不再搜索此密钥
  • 所以这里所有的键都有相同的长度,这意味着它将替换第一个
    key=>value
    元素,然后是第二个元素,依此类推

    因此,将替换第一个
    “a”=>“b”
    ,这将更改您的起始字符串:

     a b c 
    ↑↑↑ Match
    
    为此:

     b b c
    ↑↑↑ Replacement
    
    还记得我们说过的吗,在替换值之后,它不再搜索它了?确切地现在它搜索
    “b”=>“a”
    ,但只搜索字符串的这一部分:

    a b c 那么这里发生了什么

    $text = " a b c ";
    $text = strtr($text, array(" a " => " b ", " b " => " a ", " c " => " d "));
    
    首先,你必须知道:

  • 最长的钥匙将首先更换
  • 被替换后,它不再搜索此密钥
  • 所以这里所有的键都有相同的长度,这意味着它将替换第一个
    key=>value
    元素,然后是第二个元素,依此类推

    因此,将替换第一个
    “a”=>“b”
    ,这将更改您的起始字符串:

     a b c 
    ↑↑↑ Match
    
    为此:

     b b c
    ↑↑↑ Replacement
    
    还记得我们说过的吗,在替换值之后,它不再搜索它了?确切地现在它搜索
    “b”=>“a”
    ,但只搜索字符串的这一部分:

    a b c 没有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);
    
    并使用带有
    内爆的空字符串

    一种不带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);
    


    使用空字符串时,字符串中的空格数量与以前的问题相同:空格太多。为什么阵列中有这些额外的空间?这就是导致你生病的原因issue@CodeGodie确保这些词不是另一个词的一部分。例如,单词“no”是“nobody”的一部分,如果替换字符串中的所有“no”,它也将替换类似“nobody”的单词;明白了。您应该编辑您的问题并将其放在那里,这将有助于我们为您提供更好的解决方案answer@CodeGodie可以我更新了它。现在看起来有点复杂。字符串中的空格数量不一致
    “abc”
    与以前一样的问题:空格太多。为什么阵列中有这些额外的空间?这就是导致你生病的原因issue@CodeGodie确保这些词不是另一个词的一部分。例如,单词“no”是“nobody”的一部分,如果替换字符串中的所有“no”,它也将替换类似“nobody”的单词;明白了。您应该编辑您的问题并将其放在那里,这将有助于我们为您提供更好的解决方案answer@CodeGodie可以我更新了它。现在它看起来有点复杂。我该如何修复它?另外,请阅读我的最新更新,以及为什么我在单词周围加上空格。看起来那些40K的名声并不是没有意义的!你真聪明!谢谢此答案假定要替换的字符串仅由单词字符组成。这是一个合理的假设,但我认为最好明确地说明这个假设,因为当字符串的开头/结尾被替换为非单词字符或包含正则表达式元字符时,行为会变得不稳定。@nhahtdh因为在OP的代码中不需要它,所以我没有对它们进行转义。刚刚更新了我的答案,刚刚开始case@jessica两者都可以,但如果涉及regex元字符,例如dot
    ,则只有新版本才能正常工作。如何修复它?另外,请阅读我的最新更新,以及为什么我在单词周围加上空格。看起来那些40K的名声并不是没有意义的!你真聪明!谢谢此答案假定要替换的字符串仅由单词字符组成。这是一个合理的假设,但我认为最好明确地说明这个假设,因为当字符串的开头/结尾被替换为非单词字符或包含正则表达式元字符时,行为会变得不稳定。@nhahtdh因为在OP的代码中不需要它,所以我没有对它们进行转义。刚刚更新了我的答案,刚刚开始case@jessica两者都会,但如果涉及正则表达式元字符,例如点
    ,则只有新版本才能正常工作。