PHP字检查与保持原始大写

时间:2013-08-14 17:00:08

标签: php regex preg-replace

我们希望审查我们网站上的某些字词,但每个字都有不同的审查输出。

例如:

PHP => P * P,javascript => Ĵ* vascript

(但不一定是第二个字母。)

所以我们想要一个简单的“一星级”审查制度,但要保留原始上限。来自数据库的数据是未经审查的,因此我们需要尽可能快的方式。

$data="Javascript and php are awesome!";

$word[]="PHP";
$censor[]="H";//the letter we want to replace

$word[]="javascript";
$censor[]="a"//but only once (j*v*script would look wierd)
//Of course if it needed we can use the full censored word in $censor variables

预期价值: J * vascript和p * p真棒!

感谢所有答案!

5 个答案:

答案 0 :(得分:3)

您可以将删失的单词放在基于键的数组中,数组的值应该是*替换char的位置(参见$censor数组示例)。

$string = 'JavaSCRIPT and pHp are testing test-ground for TEST ŠĐČĆŽ ŠĐčćŽ!';

$censor = [
    'php' => 2,
    'javascript' => 2,
    'test' => 3,
    'šđčćž' => 4,
];

function stringCensorSlow($string, array $censor) {
    foreach ($censor as $word => $position) {
        while (($pos = mb_stripos($string, $word)) !== false) {
            $string = 
                mb_substr($string, 0, $pos + $position - 1) . 
                '*' . 
                mb_substr($string, $pos + $position);
        }
    }
    return $string;
}

function stringCensorFast($string, array $censor) {
    $pattern = [];
    foreach ($censor as $word => $position) {
        $word = '~(' . mb_substr($word, 0, $position - 1) . ')' . mb_substr($word, $position - 1, 1) . '(' . mb_substr($word, $position) . ')~iu';
        $pattern[$word] = '$1*$2';
    }
    return preg_replace(array_keys($pattern), array_values($pattern), $string);
}

使用示例:

echo stringCensorSlow($string, $censor);
# J*vaSCRIPT and p*p are te*ting te*t-ground for TE*T ŠĐČ*Ž ŠĐč*Ž!

echo stringCensorFast($string, $censor) . "\n";
# J*vaSCRIPT and p*p are te*ting te*t-ground for TE*T ŠĐČ*Ž ŠĐč*Ž!

速度测试:

foreach (['stringCensorSlow', 'stringCensorFast'] as $func) {
    $time = microtime(true);
    for ($i = 0; $i < 10000; $i++) {
        $func($string, $censor);
    }
    $time = microtime(true) - $time;
    echo "{$func}() took $time\n";
}
我的localhost上的

输出是:

stringCensorSlow() took 1.9752140045166
stringCensorFast() took 0.11587309837341

升级#1:添加了多字节字符安全。

升级#2:preg_replace添加了一个比mb_substr更快的示例。 Tnx到AbsoluteƵERØ

升级#3:在我的本地PC机上添加了速度测试循环和结果。

答案 1 :(得分:2)

制作一系列单词和替换。这在处理方面应该是您最快的选择,但设置更有条理。请记住,当您设置模式以使用i修饰符使每个模式不区分大小写时。您最终可以将这些数据从数据库中提取到数组中。我已经在这里对数组进行了硬编码。

<!DOCTYPE html>
<html>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<?php

$word_to_alter = array(
'!(j)a(v)a(script)(s|ing|ed)?!i',
'!(p)h(p)!i',
'!(m)y(sql)!i',
'!(p)(yth)o(n)!i',
'!(r)u(by)!i',
'!(ВЗЛ)О(М)!iu',
);

$alteration = array(
'$1*$2*$3$4',
'$1*$2',
'$1*$2',
'$1$2*$3',
'$1*$2',
'$1*$2',

);

$string = "Welcome to the world of programming. You can learn PHP, MySQL, Python, Ruby, and Javascript all at your own pace. If you know someone who uses javascripting in their daily routine you can ask them about becoming a programmer who writes JavaScripts. взлом прохладно";

$newstring = preg_replace($word_to_alter,$alteration,$string);

echo $newstring;

?>

</html>

<强>输出

  

欢迎来到编程世界。你可以学习P * P,M * SQL,Pyth * n,   R * by和J * v *脚本都按照您自己的节奏。如果你认识某人   在日常生活中使用j * v *脚本,你可以问他们   成为编写J * v * Scripts的程序员。 взл*мпрохладно

<强>更新

它与UTF-8字符的作用相同,请注意you have to specify a u modifier以将模式视为UTF-8。

  你好(PCRE_UTF8)       此修饰符打开与Perl不兼容的PCRE的其他功能。模式字符串被视为UTF-8。这个   在Unix和PHP上,可以从PHP 4.1.0或更高版本获得修饰符   4.2.3在win32上。从PHP 4.3.5开始检查模式的UTF-8有效性。

答案 2 :(得分:1)

为什么不使用一个小帮手功能并传递一个单词和所需的检查器?

function censorWord($word, $censor) {
    if(strpos($word, $censor)) {
        return preg_replace("/$censor/",'*', $word, 1);
    }
}
echo censorWord("Javascript", "a"); // returns J*avascript
echo censorWord("PHP", "H"); // returns P*P

然后你可以检查你的单词列表中的单词,如果它是一个应该被审查的单词,你可以将它传递给该单词。然后,你也总是有原始的单词以及被审查的单词或者放回你的句子中。

这也可以通过改变preg_replace中的偏移量来轻松更改被删除的字母数。你所要做的就是保留一系列单词,在空格或其他东西上爆炸句子,然后检查in_array。如果它在数组中,请将其发送到censorWord()

<强> Demo

这是一个更完整的例子,正如你在OP中所说的那样。

function censorWord($word, $censor) {
    if(strpos($word, $censor)) {
        return preg_replace("/$censor/",'*', $word, 1);
    }
}

$word_list = ['php','javascript'];
$data = "Javascript and php are awesome!";
$words = explode(" ", $data);
// pass each word by reference so it can be modified inside our array
foreach($words as &$word) {
    if(in_array(strtolower($word), $word_list)) {
        // this just passes the second letter of the word
        // as the $censor argument
        $word = censorWord($word, $word[1]);    
    }
}

echo implode(" ", $words); // returns J*vascript and p*p are awesome!

<强> Another Demo

答案 3 :(得分:0)

你可以在某个地方存储一个被删除的单词的小写列表,如果你可以每次主演第二个字母,可以这样做:

if (in_array(strtolower($word), $censored_words)) {
    $word = substr($word, 0, 1) . "*" . substr($word, 2);
} 

如果您想更改第一个字母,可以执行以下操作:

$censored_words = array('javascript' => 'a', 'php' => 'h', 'ruby' => 'b');
$lword = strtolower($word);
if (in_array($lword, array_keys($censored_words))) {
    $ind = strpos($lword, $censored_words[$lword]);
    $word = substr($word, 0, $ind) . "*" . substr($word, $ind + 1);
}

答案 4 :(得分:0)

这就是我要做的事情:

  1. 创建一个简单的数据库(文本文件),并制作所有删失词和预期审查结果的“表”。 E.G:

    PHP --- P*P
    javascript --- j*vascript
    HTML --- HT*L
    
  2. 编写PHP代码,将数据库信息与简单的审查文件进行比较。您必须使用array explode来创建仅包含单词的数组。像这样:

    /* Opening database of censored words */
    $filename = "/files/censored_words.txt";
    $file = fopen( $filename, "r" );
    
    if( $file == false )
    {
        echo ( "Error in opening file" );
        exit();
    }
    
    /* Creating an array of words from string*/
    $data = explode(" ", $data); // What was "Javascript and PHP are awesome!" has
                                 // become "Javascript", "and", "PHP", "are", 
                                 // "awesome!". This is useful.
    
  3. 如果您的脚本找到匹配的字词,请将数据中的字词替换为列表中的删失字词。您必须先按\r\n分隔文件,最后分隔---。 (或者你选择用来分隔桌子的任何东西。)

  4. 希望这有帮助!