3

限られた正規表現の経験、私は 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. 正しく置換された 2 番目の単語の前にあるスペースが削除されました。
4

5 に答える 5

3

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;
于 2013-04-07T17:54:39.017 に答える
1

これを試して:([^\[\]])this([^\[\]])

もちろん、「この」単語に本当に必要なものを適用する必要があります。

于 2013-04-07T16:12:32.950 に答える
0

これを試して:

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

これは、最初に遭遇した場合を除いて、this後に続く場合は置換を除外します。[/no-glossary][no-glossary]

于 2013-04-07T16:35:20.360 に答える
0

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>
于 2013-04-07T16:38:47.573 に答える