1

HTMLの大きなブロックに対して検索および置換操作を実行する必要があります。htmlタグの一部であるもの(urlなど)を変更したくない-htmlタグ以外のurlも変更したくない。html( src )内にない単語を照合するための部分的な解決策があります:

 word(?!([^<]+)?>)

regexバディもこれは同じように一致すると言います:

 (?!([^<]+)?>)word

したがって、あとは、単語がURLのような文字列の一部ではないことを確認するだけです。次のようになります。

(https?|ftp|file)://[-A-Z0-9+&@#/%?=~_|$!:,.;]*[A-Z0-9+&@#/%=~_|$]

これが可能かどうかはわかりません。私の意図は、テキストに存在し、コンテンツのhtmlの一部であるURLを保持しながら、他のものに対する検索と置換の操作を許可することです。

以下に示すように、理想的なソリューションはDOGと一致し、CATに置き換えられます。

<h1>DOG</h1> -> <h1>CAT</h1>
<h1 class='DOG'>DOG</h1> -> <h1 class='DOG'>CAT</h1>

<p class='DOG'>DOG: http://www.DOG.com/DOGfood.html DOGfood is delicious.</p> -> <p class='DOG'>CAT: http://www.DOG.com/DOGfood.html CATfood is delicious.</p>

効率のためのボーナスポイント、私はほとんど私の知恵の終わりにいます。

4

1 に答える 1

1

タグにない「DOG」の一致については、一般的にはこのようにしますが、代わりにこの正規表現を使用します。

DOG(?![^<>]++>)

[^<>]++山かっこではないものの1つ以上に一致します。それが完了すると、次のことが'>'すぐに失敗を報告しない場合、バックトラックはありません。それ以上の効率は得られません。

ただし、ルックビハインドを使用してURL内にいるかどうかを判断するというアイデアは機能しません。これには可変長のルックビハインドマッチが必要であり、PHPはそれをサポートしていません。正規表現フレーバーはほとんどサポートしていません。

代わりに、代替ベースのアプローチをお勧めします。単一の正規表現で、完全なHTMLタグ、完全なURL、または単語のいずれかに一致します。

<[^<>]++>
|
(https?|ftp|file)://[A-Z0-9+&@#/%?=~_|$]++(?:[?!:,.;-]++[A-Z0-9+&@#/%=~_|$]++)*+
|
DOG

preg_replace_callback正規表現を適用するために使用し、コールバックでそれが一致したものを確認します。タグまたはURLの場合は、プラグを差し直します。「DOG」の場合は「CAT」に置き換えます。

これは、ファイル内のすべての山かっこがHTMLタグの一部であることを前提としています。ファイルにSGMLコメントが含まれている可能性がある場合は、HTMLタグ用のコメントの前に、それらの代替を追加する必要があります。同じことがCDATAセクションにも当てはまります。そしてもちろん、属性値には山括弧を含めることもできます。これは私の経験では非常にまれですが、必要に応じて処理することもできます。

于 2009-08-29T02:57:20.200 に答える