簡體   English   中英

正則表達式替換標簽之間沒有包含的單詞(非html)

[英]Regex to replace a word that is not enclosed between tags (non-html)

有限的正則表達式經驗,我正在使用preg_replace在PHP中工作。

我想替換不在[no-glossary] ... [/ no-glossary]標簽之間的指定“單詞”。 如果它們不是“單詞”和標簽之間的空格,或者如果它們是“單詞”之后的空格,那么我的表達有效,但是如果我在單詞之前放置了一個空格(已經過了)它就失敗了!

這些工作:

$html = '<p>Do not replace [no-glossary]this[/no-glossary] replace this.</p>';
$html = '<p>Do not replace [no-glossary]this [/no-glossary] replace this.</p>';

這不是:

$html = '<p>Do not replace [no-glossary] this [/no-glossary] replace this.</p>';

使用的模式逐個解釋

/                      - find
(?<!\[no-glossary\])   - Not after the [no-glossary] tag
[ ]*                   - Followed by 0 or more spaces (I think this is the problem)
\b(this)\b             - The word "this" between word boundaries
[ ]*                   - Followed by 0 or more spaces
(?!\[\/no-glossary\])  - Not before the [/no-glossary] tag
/

這是代碼:

$pattern = "/(?<!\[no-glossary\])[ ]*\b(this)\b[ ]*(?!\[\/no-glossary\])/"; 
$html = '<p>Do not replace [no-glossary] this [/no-glossary] replace this.</p>';
$html = preg_replace($pattern, "that", $html);

print $html;

輸出:

<p>Do not change [no-glossary] that [/no-glossary] changethat.</p>

問題:

  1. 標簽之間的單詞被改變了。
  2. 在正確替換的第二個單詞前面刪除了空格。

抓住白色空間:

$subject = <<<LOD
<p>Do not replace [no-glossary]this[/no-glossary] replace this.</p>
<p>Do not replace [no-glossary]this [/no-glossary] replace this.</p>
<p>Do not replace [no-glossary] this[/no-glossary] replace this.</p>
<p>Do not replace [no-glossary] this [/no-glossary] replace this.</p>
LOD;
$pattern = '`(?<!\[no-glossary])( *+)\bthis\b( *+)(?!\[/no-glossary])`';
echo $subject.'<br/>';
echo preg_replace($pattern,"$1rabbit$2",$subject); ?>

在使用RegEx模式玩一點之后,我發現Regex PCRE引擎有一些限制,所以我從另一個角度來看問題:

  1. 匹配所有[no-glossary] this [/no-glossary]this
  2. 過濾結果。

這可以使用preg_replace_callback()來完成:

PHP 5.3+要求

$pattern = "/\[no-glossary\][ ]*\bthis\b[ ]*\[\/no-glossary\]|this/"; 
$html = '<p>Do not replace [no-glossary] this [/no-glossary] replace this.</p>';

$html = preg_replace_callback($pattern, function($match){
    if($match[0] == 'this'){
        return('that');
    }else{
        return($match[0]);
    }
}, $html);

print $html;

如果您沒有運行PHP 5.3+:

$pattern = "/\[no-glossary\][ ]*\bthis\b[ ]*\[\/no-glossary\]|this/"; 
$html = '<p>Do not replace [no-glossary] this [/no-glossary] replace this.</p>';

$html = preg_replace_callback($pattern, 'replace_function', $html);

function replace_function($match){
    if($match[0] == 'this'){
        return('that');
    }else{
        return($match[0]);
    }
}
print $html;

動態:

$tag = 'no-glossary';
$find = 'this';
$replace = 'that';

$pattern = "/\[$tag\][ ]*\b$find\b[ ]*\[\/$tag\]|$find/"; 
$html = '<p>Do not replace [no-glossary] this [/no-glossary] replace this.</p>';

$html = preg_replace_callback($pattern, function($match) use($find, $replace){
    if($match[0] == $find){
        return($replace);
    }else{
        return($match[0]);
    }
}, $html);

print $html;

試試這個: ([^\\[\\]])this([^\\[\\]])

當然,你需要在'this'這個詞上應用你真正需要的東西。

試試這個:

\b(this)\b(?!(?:(?!\[no-glossary\]).)*?\[/no-glossary\])

這樣就可以排除更換this如果它后跟[/no-glossary]除非遇到[no-glossary]第一。

試試這個它只取代this

$pattern = '%([^\da-zA-Z]+)this([^\da-zA-Z]+)%si';
$html = '<p>Do not replace [no-glossary]this sdf[/no-glossary] thisreplace<p> replacethis.</p>replace this.</p>';
function Replace1($M){
//print_r($M);
    return $M[1]."that".$M[2];
}
$html = preg_replace_callback($pattern,"Replace1",$html);
print $html;

輸出:

<p>Do not replace [no-glossary]that sdf[/no-glossary] thisreplace<p> replacethis.</p>replace that.</p>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM