我想用星星替换1或2个字符的所有单词。 我目前使用此规则:
$validTxt = preg_replace("/\\b\\w{1,2}\\b/", '*', $validTxt);
但是当单词有2个字符时,它只被1个星号代替,而不是2个星号。 我需要一种快速的方法来做到这一点。即使需要100行代码,性能也是优先考虑的事项。
答案 0 :(得分:3)
$validTxt = preg_replace_callback(
'~\b\w{1,2}\b~',
function($matches) { return str_repeat('*', strlen($matches[0])); },
$validTxt
);
这样做的好处是您可以更改限制{1,2}
,而无需调整某些正则表达式=>替换阵列。
答案 1 :(得分:1)
$validTxt = preg_replace('/\b\w{1}\b/', '*', $validTxt);
$validTxt = preg_replace('/\b\w{2}\b/', '**', $validTxt);
但我在正则表达式上生锈了,不知道是否有更好的方法。
编辑:因为我看到你可以传递一个数组,所以我正在扩展这个解决方案:
$pattern = array();
$pattern[0] = '/(\b)\w{1}(\b)/';
$pattern[1] = '/(\b)\w{2}(\b)/';
$replace = array();
$replace[0] = '$\0*$\1';
$replace[1] = '$\0**$\1';
$validTxt = preg_replace($pattern, $replace, $validTxt)
好的,应该还保留旧文本周围的空白,这意味着顺序无关紧要。但是如果你想替换空格,你需要修改代码。
答案 2 :(得分:1)
好吧试试这个:
$p = array();
$p[0] = '/\b\w{1}\b/';
$p[1] = '/\b\w{2}\b/';
$r = array();
$r[0] = '*';
$r[1] = '**';
echo preg_replace($p, $r, "a") . "\n"; // prints *
echo preg_replace($p, $r, "ab") . "\n"; // prints **
答案 3 :(得分:1)
提取'e'
修饰符的完美时间,允许您将可执行代码放入替换字符串中。 (请注意,此'e'
修饰符只能与preg_replace()
一起使用。)此测试函数可以解决这个问题:
function words_to_stars($text) {
$replace = 'str_repeat("*", strlen("$0"));';
return preg_replace('/\b\w{1,2}\b/e', $replace, $text);
}
请注意,这个方法不会像nikic的回调解决方案那么快,但我想我会把这个答案放到ring anyoo中(因为很多人可能不知道这个方便的功能。)
更新:基准,哦,我的!
我很好奇哪种方法最快,多少,所以我只是使用我漂浮的方便基准函数来测量各种方法的速度。我采用了三种方法中的每一种,并创建了一个功能来干净地实现每个方法。 (请注意,我必须修改Nikic的解决方案,因为我的PHP 5.2.14不喜欢将函数直接放入preg_replace_callback()
参数的语法。)以下是测量的函数:
// Ridgerunner's "e_modifier" method:
function words_to_stars_e_modifier($validTxt) {
return preg_replace('/\b\w{1,2}\b/e',
'str_repeat("*", strlen("$0"));',
$validTxt);
}
// nikic's "callback" method (modified):
function words_to_stars_callback($validTxt) {
return preg_replace_callback('~\b\w{1,2}\b~',
'_words_to_stars_callback',
$validTxt);
}
function _words_to_stars_callback($matches) {
return str_repeat('*', strlen($matches[0]));
}
// Eva611, Matt and anubhava's "array" method:
function words_to_stars_array($validTxt) {
return preg_replace(
array('/\b\w{1}\b/', '/\b\w{2}\b/'),
array('*', '**'),
$validTxt);
}
我从这个网页上获取了文本作为测试数据,然后测量了每个函数用了多长时间来完成它的工作(在我的AMD64 3700+ Win32 XP盒子上)。以下是基准测试的结果:( Drumroll,拜托!)
e_modifier() Nreps: 133 Time: 1.050 s Function time: 0.007893 sec
callback() Nreps: 213 Time: 1.034 s Function time: 0.004856 sec
array() Nreps: 578 Time: 1.016 s Function time: 0.001758 sec
我怀疑,'e'
修饰符方法最慢。回调方法排在第二位,而Eva611,Matt和anubhava的阵列方法以压倒性优势获胜!
答案 4 :(得分:0)
// you can pass arrays in preg_replace
$pattern = array();
$censor = array();
$pattern[0] = '/\b\w{1}\b/';
$pattern[1] = '/\b\w{2}\b/';
$censor[0] = '*';
$censor[1] = '**';
$validTxt = preg_replace($pattern, $replace, $validTxt)
答案 5 :(得分:-2)
只是一个想法,但你可能能够使用一个匹配组,然后用str_repeat包裹它的strlen:
$validTxt = preg_replace("/\\b(\\w{1,2})\\b/", str_repeat('*', str_len("$1")), $validTxt);
我目前无法访问PHP dev env,因此未经测试。