12

次の文字列があります。

Lorem ipsum Test dolor sit amet, consetetur sadipscing elitr, sed diam nonumy <a href="http://Test.com/url">Test</a> eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd sed Test dolores et ea rebum. Stet clita kasd gubergren, no sea <a href="http://url.com">Test xyz</a> takimata sanctus est Lorem ipsum dolor sit amet.

ここで、タグの間ではなく、タグの外側にある文字列 'Test' を置き換えます (たとえば、'1234' に置き換えます)。

Lorem ipsum 1234 dolor sit amet, consetetur sadipscing elitr, sed diam nonumy <a href="http://Test.com/url">Test</a> eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd sed 1234 dolores et ea rebum. Stet clita kasd gubergren, no sea <a href="http://url.com">Test xyz</a> takimata sanctus est Lorem ipsum dolor sit amet.

私はこの正規表現から始めました:(?!<a[^>]*>)(Test)([^<])(?!</a>)

しかし、次の 2 つの問題は解決されていません。

  1. テキスト「Test」もタグ内で置き換えられます (例: <a href="http://Test.com/url">)
  2. タグ間のテキストは検索されたテキストと正確に一致しませんか? それも置き換えられます (例: <a href="http://url">Test xyz</a>)

誰かがこの問題を解決する解決策を持っていることを願っています。

4

5 に答える 5

20

答え

使用する

(Test)(?!(.(?!<a))*</a>)

説明

いくつかの記号の意味を思い出してください。

1)?!否定的な先読みです。たとえば、直後に:が続かないものr(?!d)をすべて選択します。rd

ここに画像の説明を入力

2) したがって、文字なしで否定的な先読みを開始しないでください。ただ(?!d)無意味です:

ここに画像の説明を入力

3)?レイジー マッチとして使用できます。たとえば.+E

123EEE

文字列全体123EEE。ただし、必要に応じて.+?E「任意の文字」 ( .+) を選択します。のみを選択します123E

答え:

プロティストの答えは、あなたが使うべきだということです(?!<a[^>]*?>)(Test)(?![^<]*?</a>)。最初にこれを短くする方法を説明しましょう。

2)で述べたように、試合前に先読みをしても意味がありません。したがって、以下は原生生物の回答と同等です。

(Test)(?![^<]*?</a>)

また、<許可されていないため、遅延一致?は不要であるため、次と同等です

(Test)(?![^<]*</a>)

これにより、間に記号Testのない が続かないすべてが選択されます。これが、前または後に表示される Test が置き換えられる理由です。</a><<a ...> .. </a>

ただし、

Lorem Test dolor <a href="http://Test.com/url">Test <strong>dolor</strong></a> eirmod

に変更されます

Lorem 1234 dolor <a href="http://1234.com/url">1234 <strong>dolor</strong></a> eirmod 

それをキャッチするために、正規表現を次のように変更できます

(Test)(?!(.(?!<a))*</a>)

これは次のことを行います:

の各文字の後にが続かないTest文字列が続かないすべての単語を選択します。***</a>***<a

ドット.が重要であることに注意してください (2) を参照)。

ネストされたリンクは HTML4 および HTML5 では違法であるため ( smth (Test)(?!(.(?!<a))*?</a>)like <a href="#">..<a href="#">...</a>..</a>).

原生主義者は言った

また、生の HTML で正規表現を使用することはお勧めしません。

私はそれに同意します。問題は、タグが閉じられていないか開かれていない場合に問題が発生することです。たとえば、ここで言及されているすべてのソリューションは変更されます

Lorem Test dolor Test <strong>dolor</strong></a> eirmod

Lorem Test dolor Test <strong>dolor</strong></a> eirmod 1234 dolores sea 1234 takimata 
于 2017-10-25T16:38:04.393 に答える
12
(?!<a[^>]*?>)(Test)(?![^<]*?</a>)

zb226 と同じですが、遅延一致で最適化されています

また、未加工の HTML で正規表現を使用することはお勧めしません。

于 2012-09-19T11:48:17.860 に答える
4

これでうまくいくはずです:

(?!<a[^>]*>)(Test)(?![^<]*</a>)

正規表現で自分で試してください

フォローアップ: Adamが上記で説明したように、最初の部分は効果がなく、完全に削除できます。

(Test)(?![^<]*</a>)
于 2012-09-19T11:24:03.863 に答える
3

言及されていない簡単な解決策があったため、この古くからの質問を復活させます。

正規表現を使用して html を解析することに関するすべての免責事項があるので、これを行う簡単な方法を次に示します。

Perl / PCRE のメソッド

<a[^>]*>[^<]*<\/a(*SKIP)(*F)|Test

デモ

一般的な解決策

<a[^>]*>[^<]*<\/a|(Test)

このバージョンでは、置換されるテキストはグループ 1 でキャプチャされ、置換は単純なコールバックまたはラムダによって実行されます。

デモ

参照

  1. 状況 s1、s2、s3 以外でパターンを一致させる方法
  2. コードの実装については、次の場合を除き、パターンを一致させる方法のコード サンプルを参照してください。
于 2014-05-15T00:06:36.343 に答える