I have a single regex and I want to replace each match in the array of matches with a corresponding array of replacements in the most efficient way possible.
我有一个正则表达式,我想以最有效的方式替换匹配数组中的每个匹配与相应的替换数组。
So for instance, I have:
例如,我有:
$string = '~~hello~~ there, how ~~are~~ ~~you~~?';
$pattern = '/~~(.*?)~~/';
$replacements = array();
$replacements[0] = 'hi';
$replacements[1] = 'am';
$replacements[2] = 'i';
and I want to turn $string
into:
我想把$ string变成:
hi there, how am i?
Initially I hoped it'd be as simple as:
最初我希望它像下面这样简单:
$string = preg_replace($pattern, $replacements, $string);
but it doesn't seem to work. So the first question is: if $replacements
is an array, then does $string
must also be an array?
但它似乎没有用。所以第一个问题是:如果$ replacements是一个数组,那么$ string也必须是一个数组吗?
Now, I can come up with (seemingly) inefficient ways to do this, like counting the number of matches and making an array filled with the appropriate number of identical regexes. But this leads us into question two: is there a more efficient way? How would you do it, PHP pros?
现在,我可以提出(看似)效率低下的方法,例如计算匹配数量并使数组填充适当数量的相同正则表达式。但这引出了我们的问题二:是否有更有效的方法?你会怎么做,PHP专业人士?
3 个解决方案
#1
2
You can use a simple eval trick here:
你可以在这里使用一个简单的eval技巧:
print preg_replace('/~~(\w+)~~/e', 'array_shift($replacements)', $st);
array_shift
will simply fetch the first entry from your replacement array.
array_shift将简单地从替换数组中获取第一个条目。
Better would be using a map though ("hello" => "hi"
).
更好的是使用地图(“hello”=>“hi”)。
#2
1
I might use preg_replace_callback
:
我可能会使用preg_replace_callback:
$string = '~~hello~~ there, how ~~are~~ ~~you~~?';
$pattern = '/~~(.*?)~~/';
var_dump(preg_replace_callback($pattern,
function($matches) {
static $replacements = array('hi', 'am', 'i'), $i = 0;
return $replacements[$i++ % count($replacements)];
},
$string));
Output:
string(19) "hi there, how am i?"
#3
1
If all you're looking to do is switch out those three specific phrases with another set of specific phrases, then you can just use str_replace
as it is much faster than preg_replace
.
如果您要做的就是用另一组特定短语切换这三个特定短语,那么您可以使用str_replace,因为它比preg_replace快得多。
$subject = "~~hello~~ there, how ~~are~~ ~~you~~?";
$matches = array('~~hello~~', '~~are~~', '~~you~~');
$replace = array('hi', 'am', 'i');
str_replace($matches, $replace, $subject);
#1
2
You can use a simple eval trick here:
你可以在这里使用一个简单的eval技巧:
print preg_replace('/~~(\w+)~~/e', 'array_shift($replacements)', $st);
array_shift
will simply fetch the first entry from your replacement array.
array_shift将简单地从替换数组中获取第一个条目。
Better would be using a map though ("hello" => "hi"
).
更好的是使用地图(“hello”=>“hi”)。
#2
1
I might use preg_replace_callback
:
我可能会使用preg_replace_callback:
$string = '~~hello~~ there, how ~~are~~ ~~you~~?';
$pattern = '/~~(.*?)~~/';
var_dump(preg_replace_callback($pattern,
function($matches) {
static $replacements = array('hi', 'am', 'i'), $i = 0;
return $replacements[$i++ % count($replacements)];
},
$string));
Output:
string(19) "hi there, how am i?"
#3
1
If all you're looking to do is switch out those three specific phrases with another set of specific phrases, then you can just use str_replace
as it is much faster than preg_replace
.
如果您要做的就是用另一组特定短语切换这三个特定短语,那么您可以使用str_replace,因为它比preg_replace快得多。
$subject = "~~hello~~ there, how ~~are~~ ~~you~~?";
$matches = array('~~hello~~', '~~are~~', '~~you~~');
$replace = array('hi', 'am', 'i');
str_replace($matches, $replace, $subject);