javascript - 用于查找元素标记名和属性的正则表达式“跳过”属性
问题描述
我正在尝试创建一个正则表达式来查找元素的标记名和属性。例如,如果我有这个:
<div id="anId" class="aClass">
我希望能够得到一个看起来像这样的数组:
["(full match)", "div", "id", "anId", "class", "aClass"]
目前,我有 regex /<(\S*?)(?: ?(.*?)="(.*?)")*>/
,但由于某种原因,它跳过了除最后一个之外的所有属性。
var str = '<div id="anId" class="aClass">'
console.log(str.match(/<(\S*)(?: ?(.*?)="(.*?)")*>/));
正则表达式101: https ://regex101.com/r/G0ncwF/2
另一个奇怪的事情:如果我*
在非捕获组之后删除,引号中的捕获组似乎以某种方式“忘记”它是懒惰的。(正则表达式101: https ://regex101.com/r/C0UwI8/2 )
为什么会发生这种情况,我该如何避免?我找不到任何对我有帮助的问题/答案(Python re.finditer match.groups() 不包含 match 中的所有组看起来很有希望,但似乎根本没有帮助我)
(注意:我知道有更好的方法来获取属性,我只是在尝试使用正则表达式)
更新:
我至少弄清楚了为什么量词似乎“忘记”了他们是懒惰的。实际上只是正则表达式一直试图匹配尖括号。我想我一定一直认为非捕获组正在“隔离”一切并防止这种情况发生,我没有看到它仍然很懒,因为它只有一个尖括号可以找到。
var str = '"foo" "bar"> "baz>"'
console.log("/\".*?\"/ produces ", str.match(/".*?"/), ", finds first quote, finds text, lazily stops at second quote");
console.log("/\".*?\">/ produces ", str.match(/".*?">/), ", finds first quote, finds text, sees second quote but doesn't see angle bracket, keeps going until it sees \">, lazily stops");
所以至少这已经解决了。但我仍然不明白为什么它会跳过除最后一个之外的所有属性。
并注意:其他使用不同技巧来查找属性的正则表达式都很好,但我主要想了解为什么我的正则表达式会跳过属性,所以我可能会更好地理解正则表达式。
解决方案
与你的实验一起玩,你可以这样做:你可以扫描你不想要的东西,而不是扫描你想要的东西,然后将其过滤掉:
const html = '<div id="anId" class="aClass">';
const regex = /[<> ="]/;
let result = html.split(regex).filter(Boolean);
console.log('result: '+JSON.stringify(result));
输出:
result: ["div","id","anId","class","aClass"]
解释:
- 正则表达式
/[<> ="]/
列出您不想要的所有字符 .split(regex)
沿不需要的字符拆分您的文本.filter(Boolean)
摆脱不需要的字符
请注意,这有缺陷,例如它会为 html 错误地拆分<div id="anId" class="aClass anotherClass">
,例如属性值中的空格。为了支持这一点,您可以使用另一个正则表达式预处理 html 以转义引号中的空格,然后使用另一个正则表达式进行后处理以恢复空格...
是的,对于这类任务,HTML 解析器更可靠。
推荐阅读
- r - 使用错误消息确定操作过程
- android - 如何使用android管理api管理个人资料?
- c# - 被碰撞体击中时将对象捕捉到位置
- dictionary - 如何将图像和文本添加到传单地图的弹出窗口
- c# - 使用 dll 文件运行网站时,asp.net 核心身份登录不起作用
- sql-server - oracle时间戳6转换为sql server datetime2错误
- java - 从字符串创建 ECPublicKey
- php - Stripe checkout 不接受元数据
- javascript - 如何使用 axios HTTP 客户端在 node.js 中使用 ContextualWeb News API?
- django - 如何通过 post JSON 使用 CreateAPIView 创建模型实例