我认为这个正则表达式应该匹配一个 html 开始标签。
var results = html.match(/<(\/?)(\w+)([^>]*?)>/);
我看到它应该首先捕获<
,但是我很困惑这个捕获(\/?)
完成了什么。我是否正确推理除了> = 0次([^>]*?)>
之外的每个字符的搜索?>
如果是这样,为什么(\w+)
需要捕获?不属于自己的职权范围吗[^>]*?
我认为这个正则表达式应该匹配一个 html 开始标签。
var results = html.match(/<(\/?)(\w+)([^>]*?)>/);
我看到它应该首先捕获<
,但是我很困惑这个捕获(\/?)
完成了什么。我是否正确推理除了> = 0次([^>]*?)>
之外的每个字符的搜索?>
如果是这样,为什么(\w+)
需要捕获?不属于自己的职权范围吗[^>]*?
使用 debuggex 的强大功能为您生成图像:)
<(\/?)(\w+)([^>]*?)>
会被这样评价
如您所见,它匹配 HTML 标记(开始和结束标记)。正则表达式包含三个捕获组,捕获以下内容:
(\/?)
存在/
(如果存在,它是一个结束标签)(\w+)
标签的名称([^>]*?)
在标签关闭之前的所有其他内容(例如属性)这样就匹配了<a href="#">
。有趣的是,它没有<a data-fun="fun>nofun">
正确匹配,因为它停在>
属性内data-fun
。虽然(我认为)>
在属性值中是有效的。
另一个有趣的事情是,标记名称捕获并没有捕获所有理论上有效的 XHTML 标记。XHTML 允许Letter | Digit | '.' | '-' | '_' | ':' | ..
(来源:XHTML 规范)。(\w+)
但是,不匹配.
,-
和:
。<.foobar>
此正则表达式不会匹配虚构的标签。不过,这不应该对现实生活产生任何影响。
您会看到使用 RgExes 解析 HTML 是一件有风险的事情。使用 HTML 解析器可能会更好。
一个令牌一个令牌:
/
开始正则表达式文字<
匹配文字<
(\/?)
匹配 0 或 1 ( ?
) 字面/
量,由\
(\w+)
匹配一个或多个“单词字符”([^>]*?)
lazily* 匹配零个或多个 ( *?
) 任何不是>
>
匹配文字>
/
结束正则表达式文字懒惰* - 添加“?” 在重复量词之后将使其延迟执行,这意味着正则表达式将匹配前面的标记最少次数。请参阅文档。
所以本质上这个正则表达式将匹配“<”,可能后跟一个“/”,后跟任意数量的字母、数字或下划线,然后是不是“>”的任何内容,最后是一个“>” .
话虽如此,令牌并不是多余的,因为它确保在and(\w+)
之间至少有一个单词字符。<
>
(\/?)
匹配,并捕获任何结束标记,例如</i>
可能,或者</strong>
如果您熟悉它们?
另一件需要注意的是,\w
它实际上是字符类[a-zA-Z_\d]
,因此其他字符(如=
,"
等)不匹配,但会被 匹配[^>]
。是的,你对那一点是正确的。
回答你的最后一个问题,(\w+)
并不([^>]*?)
多余。它们都在表达式中发挥重要作用。
此表达式查找开始或结束标记。
(\/?)
匹配 a /
,但?
使其可选。
(\w+)
匹配单词字符,旨在匹配此处的标签名称。
([^>]*?)
旨在匹配属性。
所以如果你有字符串<div class="text">
,
(\w+)
表达式中的 the 将匹配,div
而 the([^>]*?)
将匹配class="text"
演示(在 ruby 中,不是 javascript,但没有区别):http ://www.rubular.com/r/bhw2O28qUr
总而言之,就是捕获结束标签。