正規表現はタグ間のすべてのテキストを選択します


143

2つのタグの間のすべてのテキストを選択する最良の方法は何ですか-例:ページ上のすべての「pre」タグの間のテキスト。


2
最善の方法は、Pythonを使用している場合は、「Beautiful Soup」のようなHTMLパーサーを使用することです...
Fredrik Pihl

1
最良の方法は、XML / HTMLパーサーを使用することです。
ダニエルオハラ

4
一般的には、パースHTMLに正規表現を使用することは良い考えではありません。stackoverflow.com/questions/1732348/...
murgatroid99

タグを任意にネストするとHTMLが非正規になるため、正規表現を使用してタグ間のテキストを解析しないでください。タグの一致は問題ないようです。 /<div>.*?<\/div>/.exec("<div><div></div></div>")
jdh8 2017

回答:


157

を使用"<pre>(.*?)</pre>"して(preを任意のテキストに置き換えて)最初のグループを抽出できます(より具体的な手順については、言語を指定します)。これは、非常に単純で有効なHTMLがあるという単純な概念を前提としています。

他のコメンターが示唆しているように、複雑なことをしている場合は、HTMLパーサーを使用してください。


41
これはタグのテキスト選択するのではなく、タグを含みます。
capikaw 2017

3
()を使用して選択範囲を取得する必要があります
Sahu V Kumar

2
複数行のタグの場合:<html_tag>(。+)((\ s)+(。+))+ <\ / html_tag>
Felipe Augusto

これはまだ可視性があるため<pre>、を試してもタグが引き続き表示される場合<pre>(.*?)<\/pre>は、(。*?)キャプチャグループではなく、完全一致によってキャプチャされたものを表示しているためです。音が安っぽいが、私はいつも思うのでしない限り、「泥棒の括弧=ペア」(が続いている?のように(?:、または(?>、すべての試合には2つのキャプチャを持っています:キャプチャグループのための完全なマッチ&1のために1。括弧が追加されるたびに、キャプチャが追加されます。両方のキャプチャを、使用している言語で取得する方法を知っている必要があります。
rbsdca 2018

137

タグは別の行で完了することができます。これが、\n追加する必要がある理由です。

<PRE>(.|\n)*?<\/PRE>

5
(.|\n)*?複数行にわたるHTMLタグを処理する場合の追加に関する重要なポイント。選択した回答は、HTMLタグが同じ行にある場合にのみ機能します。
Caleuanhopkins、2015

3
<PRE>(。| \ n | \ r \ n)*?<\ / PRE> Windowsの行末
Mark

3
(.|\n)*?charとの一致に使用しないでください。常に(単一行)修飾子.とともに使用しsます。または[\s\S]*?回避策。
WiktorStribiżew2018年

私はnotepad ++でコードコメントを選択したかったので、この答えを使用/\*(.|\n)*?\*/して、仕事をしてくれた-ありがとう
wkille

完璧な答えのおかげでそんなに
Omda

25

これは私が使用するものです。

(?<=(<pre>))(\w|\d|\n|[().,\-:;@#$%^&*\[\]"'+–/\/®°⁰!?{}|`~]| )+?(?=(</pre>))

基本的には次のようになります。

(?<=(<pre>)) 選択には先頭に追加する必要があります <pre>タグを

(\w|\d|\n|[().,\-:;@#$%^&*\[\]"'+–/\/®°⁰!?{}|~]| )これは私が適用したい正規表現にすぎません。この場合、文字、数字、改行文字、または角括弧内の例にリストされているいくつかの特殊文字を選択します。パイプ文字は|単に「OR」を意味します。

+?プラス文字は、上記の1つ以上を選択することを示します-順序は関係ありません。疑問符は、デフォルトの動作を「貪欲」から「不欲」に変更します。

(?=(</pre>))選択は</pre>タグで追加する必要があります

ここに画像の説明を入力してください

ユースケースによっては、(iまたはm)などの修飾子を追加する必要がある場合があります

  • i-大文字と小文字を区別しません
  • m-複数行検索

ここでは、Sublime Textでこの検索を実行したため、正規表現で修飾子を使用する必要はありませんでした。

JavaScriptは後読みをサポートしていません

上記の例は、PHP、Perl、Javaなどの言語で正常に動作するはず(?<=(<pre>))です。おそらく、ここでのように、各選択の結果から最初の4文字を単純に 取り除き、タグ間の正規表現一致テキスト

キャプチャない括弧については、JAVASCRIPT REGEX DOCUMENTATIONも参照してください。


正規表現を文字列に含めるには、一重引用符または二重引用符を `でエスケープする必要があることに注意してください。
デビッドズワート2018

18

以下のパターンを使用して、要素間のコンテンツを取得します。[tag]コンテンツを抽出する実際の要素に置き換えます。

<[tag]>(.+?)</[tag]>

時々、タグはを持つタグのような属性anchorを持ちhref、以下のパターンを使用します。

 <[tag][^>]*>(.+?)</[tag]>

最初の例を '<head>(。+?)</ head>'として試して、期待どおりに動作します。しかし、私は2番目のものでは結果がありません。
Alex Byrth、2016

1
これは機能しません。<[tag]>一致する<t><a><g>
マーティン・シュナイダー

2
@ MA-Maddin- Replace [tag] with the actual element you wish to extract the content fromパートを逃したと思います。
LWC、2018

2
ああ、そうです。これら[]はすべて省略されているはずです。RegExでの意味と実際には、人々が最初にコードをスキャンし、その後にテキストを読むことは、より明確になります;)
Martin Schneider

14

区切りタグを除外するには:

(?<=<pre>)(.*?)(?=</pre>)

(?<=<pre>) 後のテキストを探す <pre>

(?=</pre>) 前のテキストを探す </pre>

結果はpreタグ内にテキストで送信されます


これを使用している人々は@krishna thakorの答えを見て、コンテンツがタグの間に新しい行があるかどうかも検討できます
KingKongCoder

これは私の場合に役立ちました(改行を考慮する必要はありません)。ありがとう。
Pking

6

正規表現を使用してhtmlを解析しようとするべきではありません。この質問とその結果を確認してください。

簡単に言えば、htmlは通常の言語ではないため、正規表現では完全に解析できません。

ネストされた同様のタグがない場合は、htmlのサブセットを解析できると述べました。したがって、タグ自体の間になく、タグ自体でない限り、これは機能します。

preg_match("/<([\w]+)[^>]*>(.*?)<\/\1>/", $subject, $matches);
$matches = array ( [0] => full matched string [1] => tag name [2] => tag content )

より良いアイデアは、ネイティブDOMDocumentのようなパーサーを使用してhtmlをロードし、タグを選択して、次のような内部htmlを取得することです。

$obj = new DOMDocument();
$obj -> load($html);
$obj -> getElementByTagName('el');
$value = $obj -> nodeValue();

これは適切なパーサーなので、ネストタグなどを処理できます。


2
これがまだ賛成投票を集めているので少し不安ですが、正規表現の隣に適切な解決策を提供する唯一の回答であり、おそらく正しい方法ではないという十分な警告も追加しました...少なくとも私の答えの何がそんなに悪いのかコメントしてください。
sg3s 2017年

1
質問にはのタグが付けられていませんphp。PHPがどのように登場したのかわからない...
トリンコット

@trincotこれは7年以上前のことなので、思い出せません。いずれにせよ、正規表現とパーサーで問題を解決する例です。正規表現は優れており、phpは当時私がよく知っていたものです。
sg3s

私は理解しました、私はあなたの最初のコメントを見て、これがいくつかの反対票を説明できると思った。
トリンコット


4

これは私が見つけたすべての中で最も単純な正規表現のようです

(?:<TAG>)([\s\S]*)(?:<\/TAG>)
  1. 開始タグ(?:<TAG>)を一致から除外する
  2. ([\s\S]*)一致に空白または非空白文字を含める
  3. 終了タグ(?:<\/TAG>)を一致から除外する

3

この回答は、見回すのサポートを前提としています!これにより、開始タグと終了タグのペアの間のすべてのテキストを識別できました。それが「>」と「<」の間のすべてのテキストです。見回すと、一致する文字が消費されないため、これは機能します。

(?<=>)([\ w \ s] +)(?= </)

このHTMLフラグメントを使用して、https://regex101.com/でテストしました。

<table>
<tr><td>Cell 1</td><td>Cell 2</td><td>Cell 3</td></tr>
<tr><td>Cell 4</td><td>Cell 5</td><td>Cell 6</td></tr>
</table>

これは、3つの部分からなるゲームです。後ろ向き、コンテンツ、そして先読みです。

(?<=>)    # look behind (but don't consume/capture) for a '>'
([\w\s]+) # capture/consume any combination of alpha/numeric/whitespace
(?=<\/)   # look ahead  (but don't consume/capture) for a '</'

regex101.comからのスクリーンキャプチャ

私はそれが10の始まりとして役立つことを願っています。


ありがとうございました。これはより良い答えであるだけでなく、regex101サイトへの優れたリンクでもあります。賛成です!🙂
ショーン・フェルドマン

2

var str = "Lorem ipsum <pre>text 1</pre> Lorem ipsum <pre>text 2</pre>";
    str.replace(/<pre>(.*?)<\/pre>/g, function(match, g1) { console.log(g1); });

受け入れられた回答にはJavaScriptコードがないため、以下を追加します。


1

preg_match_all(/<pre>([^>]*?)<\/pre>/,$content,$matches)この正規表現は、タグ間のすべてを選択します。新しい行でも問題ありません(複数行で作業します。


1

Pythonでは、DOTALLフラグを設定すると、改行を含むすべてがキャプチャされます。

DOTALLフラグが指定されている場合、これは改行を含むすべての文字に一致します。docs.python.org

#example.py using Python 3.7.4  
import re

str="""Everything is awesome! <pre>Hello,
World!
    </pre>
"""

# Normally (.*) will not capture newlines, but here re.DOTATLL is set 
pattern = re.compile(r"<pre>(.*)</pre>",re.DOTALL)
matches = pattern.search(str)

print(matches.group(1))

python example.py

Hello,
World!

ドキュメント内のすべての開始タグと終了タグの間のテキストをキャプチャする

ドキュメント内のすべての開始タグと終了タグの間のテキストをキャプチャするにfinditerは、便利です。以下の例では、3つの開始<pre>タグと終了タグが文字列に含まれています。

#example2.py using Python 3.7.4
import re

# str contains three <pre>...</pre> tags
str = """In two different ex-
periments, the authors had subjects chat and solve the <pre>Desert Survival Problem</pre> with a
humorous or non-humorous computer. In both experiments the computer made pre-
programmed comments, but in study 1 subjects were led to believe they were interact-
ing with another person. In the <pre>humor conditions</pre> subjects received a number of funny
comments, for instance: “The mirror is probably too small to be used as a signaling
device to alert rescue teams to your location. Rank it lower. (On the other hand, it
offers <pre>endless opportunity for self-reflection</pre>)”."""

# Normally (.*) will not capture newlines, but here re.DOTATLL is set
# The question mark in (.*?) indicates non greedy matching.
pattern = re.compile(r"<pre>(.*?)</pre>",re.DOTALL)

matches = pattern.finditer(str)


for i,match in enumerate(matches):
    print(f"tag {i}: ",match.group(1))

python example2.py

tag 0:  Desert Survival Problem
tag 1:  humor conditions
tag 2:  endless opportunity for self-reflection



0

私はこのソリューションを使用します:

preg_match_all( '/<((?!<)(.|\n))*?\>/si',  $content, $new);
var_dump($new);

-1

(とりわけ)Javascriptでは、これは簡単です。属性と複数の行をカバーしています:

/<pre[^>]*>([\s\S]*?)<\/pre>/

-4
<pre>([\r\n\s]*(?!<\w+.*[\/]*>).*[\r\n\s]*|\s*[\r\n\s]*)<code\s+(?:class="(\w+|\w+\s*.+)")>(((?!<\/code>)[\s\S])*)<\/code>[\r\n\s]*((?!<\w+.*[\/]*>).*|\s*)[\r\n\s]*<\/pre>

6
言葉で答えを紹介・説明してください。
Andrew Regan
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.