Php 如何为preg_replace中的每个替换字符串分配一个ID,并获得匹配单词的列表
我已经有了一个可以工作的代码,但是我需要添加两个额外的特性。这段代码基本上替换了一个句子中的所有坏单词,并用点替换它(让读者看到字母的第一个单词) 我需要添加的新功能包括:Php 如何为preg_replace中的每个替换字符串分配一个ID,并获得匹配单词的列表,php,regex,preg-replace,array-map,Php,Regex,Preg Replace,Array Map,我已经有了一个可以工作的代码,但是我需要添加两个额外的特性。这段代码基本上替换了一个句子中的所有坏单词,并用点替换它(让读者看到字母的第一个单词) 我需要添加的新功能包括: 为preg_replace中的每个替换字符串分配一个具有唯一ID(自动增量)的html范围 在php变量中按相同顺序添加所有匹配的单词(包括重复的实例) 这是我当前的代码: function sanitize_badwords($string) { $list = array( "dumb",
function sanitize_badwords($string) {
$list = array(
"dumb",
"stupid",
"brainless"
);
# use array_map to generate a regex of array for each word
$relist = array_map(function($s) {
return '/(?:\b(' . $s[0] . ')(?=' . substr($s, 1) . '\b)|(?!\A)\G)\pL/';
}, $list);
# call preg_replace using list of regex
return preg_replace($relist, '<span id="bad_'.$counter.'">$1.</span>', $string);
}
echo sanitize_badwords('You are kind of dumb and brainless. Very dumb!');
我需要这样做的原因是,出于ToS原因,我无法在可爬行html中打印坏字,但我仍然需要稍后通过javascript在鼠标上方显示坏字(我可以轻松地获取$matches的内容并将其转换为javascript数组,并将其分配给所有坏字跨度的悬停状态).您可以使用
preg\u replace\u callback()
并传递$counter
引用以增加它:
$list = array("dumb", "stupid", "brainless");
$string = 'You are kind of dumb and brainless. Very dumb!';
// See comments below - Many thanks @revo
usort($list, function($a,$b) { return strlen($b) < strlen($b); });
$counter = 0 ; // Initialize the counter
$list_q = array_map('preg_quote', $list) ; // secure strings for RegExp
// Transform the string
$string = preg_replace_callback('~(' . implode('|',$list_q) . ')~',
function($matches) use (&$counter) {
$counter++;
return '<span id="bad_' . $counter . '">'
. substr($matches[0], 0, 1)
. str_repeat('.', strlen($matches[0]) - 1)
. '</span>' ;
}, $string);
echo $string;
将提供以下产出:
You are kind of <span id="bad_1">d...</span> and <span id="bad_2">b........</span>. Very <span id="bad_3">d...</span>!
You are kind of <span id="bad_1">d...</span> and <span id="bad_2">b........</span>. Very <span id="bad_3">d...</span>!
Array
(
[1] => dumb
[2] => brainless
[3] => dumb
)
你有点。。。b。。。。。。。。。非常好。。。!
排列
(
[1] =>哑巴
[2] =>无脑
[3] =>哑巴
)
探索伟大的方法!我怎样才能得到一个单一变量中所有匹配单词的列表(包括重复匹配)?@andufo我已经更新了anwser以使用函数。对于你的评论,我不太明白。您想要一个匹配数组?@andufo在输出数组中,索引与span ID匹配。在上次更新中:)我正在测试您的代码的早期版本。这个版本非常好用。谢谢接受答案。@revo已修复(我认为)。使用usort()
和strlen()
(mb_strlen()
)应该更好。非常感谢你!
You are kind of <span id="bad_1">d...</span> and <span id="bad_2">b........</span>. Very <span id="bad_3">d...</span>!
function sanitize_badwords($string, &$references) {
static $counter ;
static $list ;
static $list_q ;
if (!isset($counter)) {
$counter = 0 ;
$list = array("dumb", "stupid", "brainless");
// See comments below - Many Thanks @revo
usort($list, function($a,$b) { return strlen($b)< strlen($b) ; });
$list_q = array_map('preg_quote', $list);
}
return preg_replace_callback('~('.implode('|',$list_q).')~',
function($matches) use (&$counter, &$references){
$counter++;
$references[$counter] = $matches[0];
return '<span id="bad_'.$counter.'">'
. substr($matches[0],0,1)
. str_repeat('.', strlen($matches[0])-1)
. '</span>' ;
}, $string) ;
}
$matches = [] ;
echo sanitize_badwords('You are kind of dumb and brainless. Very dumb!', $matches) ;
print_r($matches);
You are kind of <span id="bad_1">d...</span> and <span id="bad_2">b........</span>. Very <span id="bad_3">d...</span>!
Array
(
[1] => dumb
[2] => brainless
[3] => dumb
)