web-dev-qa-db-ja.com

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

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

108
basheps

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

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

133
PyKing

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

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

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

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

基本的にそれがすることは:

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

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

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

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

enter image description here

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

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

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

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

上記の例は、PHP、Perl、Javaなどの言語で正常に動作しますが、Javascriptは後読みをサポートしないため、(?<=(<pre>))の使用を忘れて何らかの回避策を探す必要があります。おそらく、次のように、各選択の結果から最初の4文字を単純に削除します タグ間の正規表現一致

JAVASCRIPT REGEX DOCUMENTATION fornon-capturing parenthesesも参照してください

17
DevWL

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

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

タグには、anchorを持つhrefタグなどの属性が含まれる場合があり、次のパターンを使用します。

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

正規表現を使用して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();

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

6
sg3s

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

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

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

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

これを試して....

(?<=\<any_tag\>)(\s*.*\s*)(?=\<\/any_tag\>)
3
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コードがないため、それを追加します:

2
Shishir Arora

Pattern pattern = Pattern.compile( "[^<'tagname'/>]" );を使用できます

0
Ambrish Rajput

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

0
Krishna thakor

複数行の場合:

<htmltag>(.+)((\s)+(.+))+</htmltag>
0
Dilip

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

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