【发布时间】:2015-12-01 01:25:21
【问题描述】:
我正在尝试用某些单词替换字符串,但我也想按照数组中的位置顺序替换它。例如,我想替换“b c”,然后尝试替换“a b”,而不更改原始字符串中的位置。顺便说一句,这些字母应该代表实际的单词,它们不应该是另一个单词的一部分。例如,“sun”这个词是“sunflower”的一部分,“sunflower”这个词不能仅仅因为其中有“sun”这个词而被替换。
$text = "a b c";
$replacement = array("a b" => "ab","b c" => "bc");
$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);
第一个结果
ab c
第二个结果
我改变了数组中的位置,认为它会影响字符串被替换的顺序。可悲的是,它不是那样工作的,我得到了相同的结果。
$replacement = array("b c" => "bc","a b" => "ab");
ab c
此时,我意识到不是数组的位置会影响首先替换字符串的哪一部分,而是显示在原始字符串上的字符串部分的顺序决定了顺序它被替换为。
所以,我的问题是,有没有办法以某种方式使其可以根据字符串在数组中的顺序或以不同的方式替换字符串?比如我想替换
"b c"
在我尝试替换“a b”而不更改原始字符串的位置之前。那可行吗?谢谢。
【问题讨论】:
-
我想您将不得不更改正则表达式:添加一个否定的前瞻
a b(?! c\b)。见demo。 -
@stribizhev 这是您更改的代码的唯一部分吗? $replacement = array("a b(?! c\b)" => "ab","b c" => "bc");请在下面的答案中解释您的负面预测,以及它是如何工作的。
-
我只在确定这是解决问题的正确方法时才发布。否定前瞻是确保在前面的子模式匹配之后没有指定的模式。
a b(?! c\b)永远不会匹配a b后跟一个空格,然后是整个单词c。现在,问题是,这个解决方案可以外推到您的问题吗?有多少可能的上下文,替换数组有多大?如果您手动创建它,那么也许这是一个解决方案。 -
@stribizhev 老实说,我对您的方法有些困惑。也许如果您提供更详细的答案,我将能够使用它。
标签: php arrays regex string replace