1

正規表現のパターンマッチングで奇妙な動作をしました

正規表現は次のとおりです。

String regexp = "<h3.*>(.*)</h3>";

私は最初のケースを持っています:

<h3 class="pubAdTitleBlock">Title</h3>

この場合、すべて問題ありません。matcher.group(1)が「タイトル」を教えてくれます

2番目のケースでは、次のようにh3にネストされたリンクがあります。

<h3 class="pubAdTitleBlock "><a href="myLink" title="title">Title</a></h3>

これが問題です

この場合、-matcher.find()はtrue、-matcher.group(0)は完全な文字列、-しかしmatcher.group(1)は空の文字列です

なぜ ?

<h3 ..>title</h3>中と中のタイトルを抽出する必要があります<h3 ...><a ...>title</a></h3>

4

4 に答える 4

4

<h3.*><h3 class="pubAdTitleBlock "><a href="myLink" title="title">正規表現はデフォルトで欲張りマッチングアルゴリズムを使用するため、キャプチャします。>の最初の一致後に疑問符を停止する場合は、*の後に疑問符を使用する必要があります。これを試して:<h3.*?>(.*)</h3>

于 2012-09-11T13:43:58.210 に答える
3

1つ目.*はキャプチャし、キャプチャグループ間のとの" class="pubAdTitleBlock "><a href="myLink" title="title">Title</a"間にゼロ幅のスペースのみを残します。</a></h3>

次のようなものに変更する必要があります[^>]*(つまり、「>以外のもの」)。

于 2012-09-11T13:43:41.500 に答える
2

これに対する答えは、正規表現の「貪欲さ」です。正規表現で「より大きい」文字を使用します。

<h3.*>(.*)</h3>
     ^this one

最初の例と同様に、これが開始 h3 タグの末尾と一致することが予想されます。これにより、キャプチャ グループには h3 タグ内のすべてが含まれるようになります。

ただし、正規表現は貪欲です。つまり、可能な限り多くのテキストを消費しようとします。その結果、正規表現の最初の部分が得られます。

<h3.*>

このセクション全体と照合するには:

<h3 class="pubAdTitleBlock "><a href="myLink" title="title">Title</a>

一致した文字列は、正規表現 ( ) と同じ文字で終わることに注意してください>>グループは、これと </h3>空の文字列であるの間の残りのテキストをキャプチャします。

対応する解決策は 3 つあります。

  • xml パーサーを使用してから、xpath を使用して h3 タグのコンテンツを取得します (外部ライブラリなどのために多くのオーバーヘッドが発生しますが、大規模なプロジェクトでは絶対に必要です)。
  • a を追加して正規表現を作成することにより、*-operator を非貪欲にします。詳細については、こちらをご覧ください。?<h3.*?>(.*)</h3>
  • 正規表現を変更して、h3 タグ (および他のタグなし) が閉じるとすぐにキャプチャを明示的に開始するようにします。<h3[^>]*>(.*)</h3>

お役に立てれば!

于 2012-09-11T13:53:07.723 に答える
0

Namida Aneskansのおかげで、解決策は次のようになりました。

String regexp = "<h3[^>]*>(<a[^>]*>)?([^<]+)(</a>)?</h3>";

したがって、最初と3番目のグループは空にすることができますが、2番目は常にタイトルです。ありがとうございます。

于 2012-09-11T13:50:30.023 に答える