2012-09-26 24 views
0

我有一個代碼,如何編寫正確的正則表達式來刪除列出話

$text = "This is a $1ut (Y) @ss @sshole a$$ ass test with grass and passages."; 
$blacklist = array(
    '$1ut', 
    '(Y)', 
    '@ss', 
    '@sshole', 
    'a$$', 
    'ass' 
); 
foreach ($blacklist as $word) { 
    $pattern = "/\b". preg_quote($word) ."\b/i"; 
    $replace = str_repeat('*', strlen($word)); 
    $text = preg_replace($pattern, $replace, $text); 
} 
print_r($text); 

它會返回以下結果:

This is a $1ut (Y) @ss @sshole a$$ *** test with grass and passages.

當我從正則表達式中刪除字邊界,

$pattern = "/". preg_quote($word) ."/i"; 

返回:

This is a **** ***** *** ***hole *** *** test with gr*** and p***ages.

我如何寫正則表達式所以它不會取代這樣的話passagesgrass等,但完全取代,如@sshole

+5

應該補充說的是,無論你認爲帶有密碼和替換的單詞列表有多大幫助,人們總是會**試圖找到它,最終它們會。那麼它只會是assh0le或$$洞而已。 – h2ooooooo

+0

是的,我知道。因爲這個單詞會增長。但我的問題是如何編寫正則表達式。這不僅可以用來防止罵人的話,而且可以用於任何類似的情況。 –

+1

我認爲更重要的問題是爲什麼用\ b的它沒有找到你的單詞 – BugFinder

回答

3

根據this\b不支持除[A-Za-z0-9_]以外的其他任何內容。

請注意,您逃避你的正則表達式,因爲你從一個字符串產生它(和PHP的編譯器,它會創建這個字符串的時候,不知道這是一個正則表達式)。

使用正則表達式/(^|\s)WORD($|\s)/i似乎工作。

代碼示例:

$text = "This is a $1ut (Y) @ss @sshole a$$ ass test with grass and passages."; 
$blacklist = array(
    '$1ut', 
    '(Y)', 
    '@ss', 
    '@sshole', 
    'a$$', 
    'ass' 
); 
foreach ($blacklist as $word) { 
    $pattern = "/(^|\\s)" . preg_quote($word) . "($|\\s)/i"; 
    $replace = " " . str_repeat('*', strlen($word)) . " "; 
    $text = preg_replace($pattern, $replace, $text); 
} 
echo $text; 

輸出:

This is a **** ***** *** ******* *** *** test with grass and passages.

請注意,如果你的字符串開始或與這些詞結束後,我們將在添加一個空格來比賽每一端,這意味着文本之前或之後會有空格。你可以照顧這個trim()

更新;

另外請注意,這不會以任何方式解釋標點符號。

the other user has an ass. and it is nice會經歷例如。

要克服這一點,你甚至可以進一步擴展它:

/(^|\\s|!|,|\.|;|:|\-|_|\?)WORD($|\\s|!|,|\.|;|:|\-|_|\?)/i

這將意味着,你也必須改變,我們要替換的方式:

$text = "This is a $1ut (Y) @[email protected] you're an ass. a$$ ass test with grass and passages."; 
$blacklist = array(
    '$1ut', 
    '(Y)', 
    '@ss', 
    '@sshole', 
    'a$$', 
    'ass' 
); 
foreach ($blacklist as $word) { 
    $pattern = "/(^|\\s|!|,|\\.|;|:|\\-|_|\\?)" . preg_quote($word) . "($|\\s|!|,|\\.|;|:|\\-|_|\\?)/i"; 
    $replace = '$1' . str_repeat('*', strlen($word)) . '$2'; 
    $text = preg_replace($pattern, $replace, $text); 
} 
echo $text; 

,並添加所有其他標點符號等

輸出:

This is a **** ***** ***?******* you're an ***. *** *** test with grass and passages.

+0

Thx h2ooooooo!我會試一試,很快就會回來。 –

+1

@VladStratulat注意我的答案的更新。 – h2ooooooo

+0

作爲一種魅力!你更新的答案是「展望未來」。 Thx隊友!!! –