HTML 标签的反向匹配
Inverse match for HTML tags
使用 NodeJS,我有以下正则表达式:/<[^>]*>/g
匹配 HTML 标签:
(Live Demo)
我想反转匹配以便捕获文本,我尝试了 negative lookahead 方法,但没有成功。
编辑
我避免使用 split 方法,因为我需要 match
的索引
用 JS 可以吗?
Is it possible with JS?
没有。 HTML 可以任意嵌套,这意味着您需要递归才能使用正则表达式使用它 - JavaScript 正则表达式没有。
假设你可以放弃 JS 并使用支持 PCRE 的语言,这个 Cthulhu 编写的一大堆难以理解的字符正则表达式可以解决问题(mandatory regex101 link)(注意它不处理 CDATA):
<!--[\s\S]*?-->|<([a-z]+)(?:\s\S+?=(["']|)[\s\S]*?)*>((?:[\s\S]*?(?R)?)*)<\/>
工作原理如下:
<!--[\s\S]*?-->|
是为了防止评论造成误报
<([a-z]+)(?:\s\S+?=(["']|)[\s\S]*?)*>
是起始标签,其中
([a-z]+)
是标签名称(注意捕获组 - 我们将在结束标签中需要它)
(?:\s\S+?=(["']|)[\s\S]*?)*
是属性,其中
\s
是分隔属性和标签名称以及彼此的空白字符
\S+?=
是属性名称后跟一个等号(注意惰性量词 - 我们需要它,因为 \S
包括 =
)
(["']|)[\s\S]*?
是值,可以用双引号、单引号或什么都不括起来
((?:[\s\S]*?(?R)?)*)
是标签之间的文本(注意捕获组 - 这正是您所需要的,将显示为组 3),其中 (?R)?
使正则表达式能够处理嵌套结构
<\/>
是结束标签,其中
是标签名(记住开始标签中的捕获组)
由于给出的答案没有给出任何解决方案,因此您可以使用以下代码来简化没有嵌套标签的 [x]html。否则,要获得完整的解决方案,请使用 HTML 解析器。
var str = "Lorem ipsum <pre class='a1'>text 1</pre> Lorem ipsum <a href='http://google.com'>text 2</a>";
str.replace(/<(\w+).*>(.*?)<\/>/g, function(match, g1, g2) { console.log(g2); });
使用 NodeJS,我有以下正则表达式:/<[^>]*>/g
匹配 HTML 标签:
(Live Demo)
我想反转匹配以便捕获文本,我尝试了 negative lookahead 方法,但没有成功。
编辑 我避免使用 split 方法,因为我需要 match
的索引用 JS 可以吗?
Is it possible with JS?
没有。 HTML 可以任意嵌套,这意味着您需要递归才能使用正则表达式使用它 - JavaScript 正则表达式没有。
假设你可以放弃 JS 并使用支持 PCRE 的语言,这个 Cthulhu 编写的一大堆难以理解的字符正则表达式可以解决问题(mandatory regex101 link)(注意它不处理 CDATA):
<!--[\s\S]*?-->|<([a-z]+)(?:\s\S+?=(["']|)[\s\S]*?)*>((?:[\s\S]*?(?R)?)*)<\/>
工作原理如下:
<!--[\s\S]*?-->|
是为了防止评论造成误报<([a-z]+)(?:\s\S+?=(["']|)[\s\S]*?)*>
是起始标签,其中([a-z]+)
是标签名称(注意捕获组 - 我们将在结束标签中需要它)(?:\s\S+?=(["']|)[\s\S]*?)*
是属性,其中\s
是分隔属性和标签名称以及彼此的空白字符\S+?=
是属性名称后跟一个等号(注意惰性量词 - 我们需要它,因为\S
包括=
)(["']|)[\s\S]*?
是值,可以用双引号、单引号或什么都不括起来
((?:[\s\S]*?(?R)?)*)
是标签之间的文本(注意捕获组 - 这正是您所需要的,将显示为组 3),其中(?R)?
使正则表达式能够处理嵌套结构<\/>
是结束标签,其中是标签名(记住开始标签中的捕获组)
由于给出的答案没有给出任何解决方案,因此您可以使用以下代码来简化没有嵌套标签的 [x]html。否则,要获得完整的解决方案,请使用 HTML 解析器。
var str = "Lorem ipsum <pre class='a1'>text 1</pre> Lorem ipsum <a href='http://google.com'>text 2</a>";
str.replace(/<(\w+).*>(.*?)<\/>/g, function(match, g1, g2) { console.log(g2); });