Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何为preg_replace中的每个替换字符串分配一个ID,并获得匹配单词的列表_Php_Regex_Preg Replace_Array Map - Fatal编程技术网

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",

我已经有了一个可以工作的代码,但是我需要添加两个额外的特性。这段代码基本上替换了一个句子中的所有坏单词,并用点替换它(让读者看到字母的第一个单词)

我需要添加的新功能包括:

  • 为preg_replace中的每个替换字符串分配一个具有唯一ID(自动增量)的html范围

  • 在php变量中按相同顺序添加所有匹配的单词(包括重复的实例)

  • 这是我当前的代码:

    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
    )