具有奇怪行为的正则表达式

2024-04-26 14:18:08 发布

您现在位置:Python中文网/ 问答频道 /正文

在过去的两天里我一直在努力解决这个问题。。。你知道吗

请帮助我理解为什么会这样。我的意图是只选择具有<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>

有人能帮我吗?你知道吗


Tags: 字符串hdrval意图abcsvaldtl2dtl1
2条回答

卡西米尔和希波莱特已经给了你一些好的解决方案。我想详细说明几件事。你知道吗

首先,您的正则表达式为什么不能做您想做的事情:(?<=<HDR>).*?告诉它匹配任何数量的字符,从前面的第一个字符开始,直到它遇到非贪婪量词(<DTL1...)后面的字符。好的,前面加<HDR>的第一个字符是第一个a,所以它匹配从那里开始的所有内容,直到遇到固定字符串<DTL1\sval="3"。你知道吗

Casimir et Hippolyte的解决方案适用于一般情况,<;HDR>;标记的内容可以是嵌套的<;HDR>;以外的任何内容。您也可以通过积极的前瞻性来实现这一点:

(?<=<HDR>)(.(?!</HDR>))*<DTL1\sval="3".*?</HDR>

但是,如果字符串保证在所示的结构中,<;HDR>;标记只包含一个或多个<;DTL1 val=“##”>;标记,那么您知道其中不会有任何结束标记,您可以更有效地将第一个.*?替换为[^/]*

(?<=<HDR>)[^/]*<DTL1\sval="3".*?</HDR>

否定字符类比零宽度断言更有效,如果使用的是否定字符类,贪婪的量词将比懒惰的量词更有效。你知道吗

另请注意,通过使用lookback匹配开头<;HDR>;,您将其从匹配中排除,但您将包括结尾<;/HDR>;。你确定这就是你想要的吗?你在匹配这个。。。你知道吗

<DTL1 val="3"><DTL2 val="4"></HDR>

…当你想要这个的时候。。。你知道吗

<HDR><DTL1 val="3"><DTL2 val="4"></HDR>

…或者这个。。。你知道吗

<DTL1 val="3"><DTL2 val="4">

所以,在第一种情况下,不要使用lookback作为开始标记:

<HDR>(.(?!</HDR>))*<DTL1\sval="3".*?</HDR>
<HDR>[^/]*<DTL1\sval="3".*?</HDR>

在第二种情况下,对结束标记使用前瞻:

(?<=<HDR>)(.(?!</HDR>))*<DTL1\sval="3".*?(?=</HDR>)
(?<=<HDR>)[^/]*<DTL1\sval="3".*?(?=</HDR>)

正则表达式引擎将始终为您提供字符串中最左边的匹配(即使您使用非贪婪量词)。这正是你得到的。你知道吗

因此,一个解决方案是禁止在.*?所描述的部分中存在另一个<HDR>过于允许。你知道吗

有两种方法可以做到这一点,可以用以下方法替换.*?

(?>[^<]+|<(?!/HDR))*

或与:

(?:(?!</HDR).)*+

大多数情况下,第一种技术的性能更高,但是如果字符串包含高密度的<,那么第二种方法也可以得到很好的结果。你知道吗

使用possessive quantifieratomic group可以减少获得结果的步骤数,特别是在子模式失败时。你知道吗

示例:

第一种方式:

(?<=<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>

相关问题 更多 >