正则表达式与背后奇怪的行为
regex with lookbehind weird behavior
在过去的两天里,我一直在尝试解决这个问题......
请帮助我理解为什么会发生这种情况。我的目的是只选择具有<DTL1 val="92">.....</HDR>
的<HDR>
这是我的正则表达式
(?<=<HDR>).*?<DTL1'sval="3".*?</HDR>
输入字符串为:
<HDR>abc<DTL1 val="1"><DTL2 val="2"></HDR><HDR><DTL1 val="92"><DTL2 val="55"></HDR><HDR><DTL1 val="3"><DTL2 val="4"></HDR>
但是这个正则表达式选择
abc<DTL1 val="1"><DTL2 val="2"></HDR><HDR><DTL1 val="92"><DTL2 val="55"></HDR>
谁能帮我?
则表达式引擎将始终为您提供字符串中最左侧的匹配项(即使您使用非贪婪量词(。这正是你得到的。
因此,一种解决方案是禁止在.*?
描述的过于宽松的部分中存在另一种<HDR>
。
您有两种技术可以做到这一点,您可以将.*?
替换为:
(?>[^<]+|<(?!/HDR))*
或与:
(?:(?!</HDR).)*+
大多数时候,第一种技术的性能更高,但是如果您的字符串包含高密度的<
,第二种方法也可以产生良好的结果。
使用所有格量词或原子组可以减少获得结果的步骤数,尤其是在子模式失败时。
例:
第一种方法:
(?<=<HDR>)(?>[^<]+|<(?!/HDR))*<DTL1'sval="3"(?>[^<]+|<(?!/HDR))*</HDR>
或此变体:
(?<=<HDR>)(?:[^<]+|<(?!/HDR|DTL1))*+<DTL1'sval="3"(?:[^<]+|<(?!/HDR))*+</HDR>
第二种方式:
(?<=<HDR>)(?:(?!</HDR).)*<DTL1'sval="3"(?:(?!</HDR).)*+</HDR>
或此变体:
(?<=<HDR>)(?:(?!</HDR|DTL1).)*+<DTL1'sval="3"(?:(?!</HDR).)*+</HDR>
Casimir et Hippolyte已经给了你几个很好的解决方案。我想详细说明几件事。
首先,为什么你的正则表达式不能做你想要的:(?<=<HDR>).*?
告诉它匹配从第一个字符开始的任意数量的字符,前面是<HDR>
,直到它遇到非贪婪量词(<DTL1...
(后面的内容。好吧,前面的第一个字符 <HDR>
是第一个a
,因此它匹配从那里开始的所有内容,直到遇到固定字符串<DTL1'sval="3"
。
Casimir et Hippolyte的解决方案适用于广义情况,其中
(?<=<HDR>)(.(?!</HDR>))*<DTL1'sval="3".*?</HDR>
但是,如果保证字符串位于所示结构中,其中 .*?
替换为 [^/]*
来更有效地做到这一点:
(?<=<HDR>)[^/]*<DTL1'sval="3".*?</HDR>
否定字符类比零宽度断言更有效,如果使用否定字符类,贪婪量词将比惰性量词更有效。
另请注意,通过使用后视来匹配开场
<DTL1 val="3"><DTL2 val="4"></HDR>
。当大概你想要这个...
<HDR><DTL1 val="3"><DTL2 val="4"></HDR>
。或者这个...
<DTL1 val="3"><DTL2 val="4">
因此,在第一个情况下,不要对开始标记使用回溯:
<HDR>(.(?!</HDR>))*<DTL1'sval="3".*?</HDR>
<HDR>[^/]*<DTL1'sval="3".*?</HDR>
在第二种情况下,对结束标记使用前瞻:
(?<=<HDR>)(.(?!</HDR>))*<DTL1'sval="3".*?(?=</HDR>)
(?<=<HDR>)[^/]*<DTL1'sval="3".*?(?=</HDR>)
- java.net和javascript之间正则表达式的差异
- Grunt匹配正则表达式
- 不同浏览器中的空白字符正则表达式行为
- 正则表达式在字符串中找到base64
- 子字符串/正则表达式以获取字符串中保存的 SRC 值
- 调用正则表达式匹配的函数
- 使用正则表达式评估电子邮件地址时出现性能问题
- Javascript 正则表达式 : ^[^/s/]+[a-z]{1,}[0-9]*[-_]*[^/][
- JavaScript正则表达式文本与RegExp对象
- 正则表达式只允许 x 个整数
- 使用正则表达式将输入格式设置为单字符逗号、单字符逗号等
- 改进用于验证付款金额的正则表达式
- 正则表达式与数字中的第二个点匹配
- 键按正则表达式以查找具有负值的小数
- 一个正则表达式,用于从JS中的HTML标记中删除id、样式和类属性
- 将po-box javascript正则表达式转换为c#regex
- 为什么我在正则表达式背后的积极看法无效
- 正则表达式,负面的 JavaScript 背后的外观
- 正则表达式与背后奇怪的行为
- 理解JavaScript中正则表达式背后的积极含义