正则表达式选择标签之间的所有文本

bas*_*eps 115 html regex html-parsing

选择2个标签之间所有文本的最佳方法是什么 - 例如:页面上所有"pre"标签之间的文本.

PyK*_*ing 140

你可以使用"<pre>(.*?)</pre>"(用你想要的任何文本替换pre)并提取第一组(更具体的指令指定语言),但这假设你有非常简单和有效的HTML的简单概念.

正如其他评论者所建议的那样,如果您正在做一些复杂的事情,请使用HTML解析器.

  • 这不会选择文本_between_标签,它包括标签. (32认同)
  • 您需要使用 () 获取选择 (3认同)
  • 对于多行标签:&lt;html_tag&gt;(.+)((\s)+(.+))+&lt;\/html_tag&gt; (3认同)
  • 这仍然具有可见性,因此:如果您在尝试 `&lt;pre&gt;(.*?)&lt;\/pre&gt;` 后仍然看到 `&lt;pre&gt;` 标签,那是因为您正在查看完整匹配捕获的内容(.*?) 捕获组的。听起来很俗气,但我总是认为“括号 = 小偷对”,因为除非 `(` 后跟一个 `?`,如 `(?:` 或 `(?&gt;`,每场比赛都会有两个捕获:1捕获组的完全匹配和 1。每组额外的括号添加一个额外的捕获。您只需要知道如何以您正在使用的任何语言检索这两个捕获。 (2认同)

zac*_*zac 118

标签可以在另一行中完成.这就是\n需要添加的原因.

<PRE>(.|\n)*?<\/PRE>
Run Code Online (Sandbox Code Playgroud)

  • 关于在多行中处理HTML标记时添加`(.| \n)*?`的重点.仅当HTML标记位于同一行时,所选答案才有效. (3认同)
  • Windows行结尾的<PRE>(.| \n |\r \n)*?<\/PRE> (3认同)
  • 切勿使用(。| \ n)*?来匹配任何字符。始终将`.`与`s`(singleline)修饰符一起使用。或者是[[\ s \ S] *?`解决方法。 (2认同)

Dev*_*vWL 18

这就是我要用的.

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

基本上它的作用是:

(?<=(<pre>))选择必须以<pre>标签为前缀

(\w|\d|\n|[().,\-:;@#$%^&*\[\]"'+–/\/®°?!?{}|~]| )这只是我想要应用的正则表达式.在这种情况下,它会选择字母或数字或换行符或方括号中示例中列出的一些特殊字符.管道字符|仅表示" OR ".

+?加上字符状态以选择上述一个或多个 - 顺序无关紧要.问号将默认行为从"贪婪"更改为"未批准".

(?=(</pre>))选择必须附加</pre>标签

在此输入图像描述

根据您的使用情况,您可能需要添加一些修饰符,如(im)

  • - 不区分大小写
  • m - 多行搜索

在这里,我在Sublime Text中执行了此搜索,因此我不必在我的正则表达式中使用修饰符.

Javascript不支持lookbehind

上面的例子应该适用于PHP,Perl,Java等语言...但是,Javascript不支持lookbehind所以我们不得不忘记使用(?<=(<pre>))并寻找某种解决方法.也许从我们的结果中为每个选项简单地删除前四个字符,就像在这里使用 标记之间的正则表达式匹配文本一样

另请参阅JAVASCRIPT REGEX DOCUMENTATION以了解非捕获括号


Shr*_*thy 15

使用以下模式获取元素之间的内容.将[tag]替换为您要从中提取内容的实际元素.

<[tag]>(.+?)</[tag]>
Run Code Online (Sandbox Code Playgroud)

有时标签都会有属性,如[tag]具有标签anchor,然后用下面的模式.

 <[tag][^>]*>(.+?)</[tag]>
Run Code Online (Sandbox Code Playgroud)

  • @ MA-Maddin-我想您错过了用您希望从中提取内容的实际元素替换“标签”的操作。 (2认同)
  • 哦,是的。这些`[]`应该已经完全省略了。由于它们在RegEx中的含义以及人们首先扫描代码然后阅读文本的事实,这将更加清楚。 (2认同)

Cla*_*ius 14

这个答案假设支持环顾四周!这使我能够识别成对的开始和结束标签之间的所有文本。这就是“>”和“<”之间的所有文本。它起作用是因为环顾四周不会消耗它匹配的字符。

(?<=>)([\w\s]+)(?=<\/)
Run Code Online (Sandbox Code Playgroud)

我使用此 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>
Run Code Online (Sandbox Code Playgroud)

这是一个由三部分组成的游戏:回顾、内容和展望。

(?<=>)    # 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 '</'
Run Code Online (Sandbox Code Playgroud)

来自 regex101.com 的屏幕截图

我希望这可以作为 10 的开始。运气。

  • 谢谢。这不仅是一个更好的答案,而且还是 regex101 网站的一个很好的链接。已投票! (3认同)

sg3*_*g3s 6

您不应该尝试使用正则表达式解析html,看看这个问题以及结果如何.

简单来说,html不是常规语言,因此无法使用正则表达式完全解析.

已经说过,当没有嵌套的类似标签时,你可以解析html的子集.因此,只要介于和之间的任何内容都不是标记本身,这将起作用:

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

一个更好的想法是使用解析器,如本机DOMDocument,加载您的HTML,然后选择您的标签,并获得内部html,可能看起来像这样:

$obj = new DOMDocument();
$obj -> load($html);
$obj -> getElementByTagName('el');
$value = $obj -> nodeValue();
Run Code Online (Sandbox Code Playgroud)

由于这是一个合适的解析器,它将能够处理嵌套标签等.

  • 只是想说我有点不安,这仍然在收集反对票,而它是唯一在正则表达式旁边提供适当解决方案的答案,我还添加了充分的警告,表明它可能不是正确的方法......请至少评论一下我的答案有什么问题。 (2认同)

maq*_*uni 6

这似乎是我发现的最简单的正则表达式

(?:<TAG>)([\s\S]*)(?:<\/TAG>)
Run Code Online (Sandbox Code Playgroud)
  1. (?:<TAG>)从匹配中排除开始标签
  2. ([\s\S]*)在匹配项中包含任何空格或非空格字符
  3. (?:<\/TAG>)从匹配中排除结束标记

  • 谢谢。在这对我有用之前,我已经把上面所有的内容都烧完了。需要一个来抓取 SCSS 和 HTML 文件——`style[lang="scss"]`的innerHTML——这就成功了。这是:https://regex101.com/r/VqhNsI/1。 (2认同)

Her*_*era 5

尝试这个....

(?<=\<any_tag\>)(\s*.*\s*)(?=\<\/any_tag\>)
Run Code Online (Sandbox Code Playgroud)

  • 请注意,JavaScript 不支持后视。 (3认同)

小智 5

要排除定界标记:

"(?<=<pre>)(.*?)(?=</pre>)"
Run Code Online (Sandbox Code Playgroud)

  • 如果您有多个元素,则这不起作用。例如,`&lt;pre&gt;第一&lt;/pre&gt;&lt;pre&gt;第二&lt;/pre&gt;` (2认同)