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

时间:2011-08-23 20:42:41

标签: html regex html-parsing

选择2个标签之间所有文字的最佳方法是什么 - 例如:页面上所有“预”标签之间的文字。

20 个答案:

答案 0 :(得分:131)

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

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

答案 1 :(得分:111)

标签可以在另一行完成。这就是为什么需要添加\n的原因。

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

答案 2 :(得分:16)

这就是我要用的。

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

基本上它的作用是:

(?<=(<pre>))选择必须以<pre>代码

作为前缀

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

+?加上字符状态以选择上述一个或多个 - 顺序无关紧要。 问号会更改&#39;贪婪&#39;的默认行为到了&#39; ungreedy&#39;。

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

enter image description here

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

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

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

Javascript不支持lookbehind

以上示例应该可以正常使用PHP,Perl,Java等语言... 但是,Javascript不支持lookbehind,因此我们不得不忘记使用(?<=(<pre>))并寻找某种解决方法。也许简单地从我们的结果中删除前四个字符,就像在这里一样 Regex match text between tags

另请查看{{3>} 非捕获括号

答案 3 :(得分:10)

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

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

有时候标签会有anchor标签有href的属性,然后使用以下模式。

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

答案 4 :(得分:6)

您不应该尝试使用正则表达式解析html,请参阅this question以及结果如何。

用最简单的术语来说,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();

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

答案 5 :(得分:4)

要排除定界标记:

<div *ngIf="myTestForm.get('bucket').hasError('required')">Input is required</div>

<div *ngIf="myTestForm.get('bucket').hasError('minlength')">Min length should be 5</div>

答案 6 :(得分:4)

这似乎是我发现的所有内容中最简单的正则表达式

(?:<TAG>)([\s\S]*)(?:<\/TAG>)
  1. 从比赛中排除开始标签(?:<TAG>)
  2. 在比赛中包含任何空格或非空格字符([\s\S]*)
  3. 从比赛中排除结束标签(?:<\/TAG>)

答案 7 :(得分:3)

试试这个......

(?<=\<any_tag\>)(\s*.*\s*)(?=\<\/any_tag\>)

答案 8 :(得分: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代码,所以添加:

答案 9 :(得分:0)

const content = '<p class="title responsive">ABC</p>';
const blog = {content};
const re = /<([^> ]+)([^>]*)>([^<]+)(<\/\1>)/;
const matches = content.match(re);
console.log(matches[3]);

matches[3] 是内容文本,它适用于任何带有类的标签名称。 (不支持嵌套结构)

答案 10 :(得分:0)

(?<=>)[^<]+

对于记事本++

>([^<]+)

用于 AutoIt(选项返回全局匹配数组)。

 (?=>([^<]+))

https://regex101.com/r/VtmEmY/

答案 11 :(得分:0)

选择我喜欢的pre标签之间的所有文本

preg_match('#<pre>([\w\W\s]*)</pre>#',$str,$matches);

<块引用>

$matches[0] 的结果包括

 标签

<块引用>

$matches[1] 将包含

 中的所有内容。

DomDocument 无法在需要在搜索标签中获取带有标签详细信息的文本的情况下工作,因为它会去除所有标签,nodeValue 和 textContent 将仅返回没有标签和属性的文本。

答案 12 :(得分:0)

此答案要求支持环顾四周!这使我能够识别成对的开始和结束标签之间的所有文本。这就是“>”和“ <”之间的所有文本。之所以有效,是因为环顾四周并不会消耗匹配的字符。

(?<=>)([\ 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>

这是一个包含三个部分的游戏:背后的外观,内容和正面的外观。

(?<=>)    # 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 '</'

screen capture from regex101.com

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

答案 13 :(得分:0)

在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很有用。在下面的示例中,字符串中包含三个打开和关闭<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

答案 14 :(得分:0)

preg_match_all(/<pre>([^>]*?)<\/pre>/,$content,$matches)此正则表达式将选择标记之间的所有内容。不管是换行(使用多行)。

答案 15 :(得分:0)

我使用这个解决方案:

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

答案 16 :(得分:0)

您可以使用Pattern pattern = Pattern.compile( "[^<'tagname'/>]" );

答案 17 :(得分:0)

对于多行:

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

答案 18 :(得分:-1)

在Javascript(以及其他)中,这很简单。它涵盖了属性和多行内容:

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

答案 19 :(得分:-3)

; Your code below
Run(@ProgramFilesDir & "\Mozilla Firefox\firefox.exe", "", @SW_MINIMIZE)
Opt("WinTitleMatchMode", 2)
WinWait("Mozilla Firefox")
WinSetState("Mozilla Firefox", "", @SW_MINIMIZE)

; Use the mouse move function to move the cursor to the 'Bookmark' icon.
MouseMove(xxxx,xxxx)
Sleep(100)
MouseClick("left")