从两个字符之间提取两个字符串。为什么我的正则表达式不匹配,我该如何改进它?

Extracting two strings from between two characters. Why doesn't my regex match and how can I improve it?

我正在学习正则表达式,我想从具有以下特征的文本中提取一个字符串:

意思是我想捕获字母 CP 之间的字符串以及字母 P 之后的字符串并将它们连接成一个字符串,同时丢弃字母 CP

有效字符串的示例为:

c45AFP2
CAPF
c56Bp26
CA6C22pAAA

对于上面的示例,我想要以相同的顺序提取以下内容:

45AF2     # Original string: c45AFP2
AF        # Original string: CAPF
56B26     # Original string: c56Bp26
A6C22AAA  # Original string: CA6C22pAAA

无效字符串的示例为:

BCA6C22pAAA  # It doesn't begin with C
c56Bp  # There aren't any characters after P
c45AF0P2  # Contains a zero

我正在使用 python,我想要一个正则表达式来提取字符 CP 之间以及 [=18= 之后的两个字符串]

到目前为止我已经想到了这个:

(?<=\A[cC])[a-fA-F1-9]*(?<=[pP])[a-fA-F1-9]*

细分为:

(?<=\A[cC]) 正面回顾断言。断言正则表达式解析器当前位置之前的内容必须匹配 [cC] 并且 [cC] 必须位于字符串的开头

[a-fA-F1-9]* 匹配列表中的单个字符零次到无限次

(?<=[pP]) 积极的回顾断言。断言正则表达式解析器当前位置之前的内容必须匹配 [pP]

[a-fA-F1-9]* 匹配列表中的单个字符零次到无限次

但是使用上面的正则表达式我无法匹配任何字符串!

当我在 (?<=[cC])[a-fA-F1-9]*(?<=[pP])[a-fA-F1-9]* 之间插入一个 | 时,它起作用了。

表示以下正则表达式有效:

(?<=[cC])[a-fA-F1-9]*|(?<=[pP])[a-fA-F1-9]*

我知道 | 意味着它应该最多匹配一个指定的正则表达式。但它是非贪婪的,它 returns 它找到的第一个匹配项。其余的表达式没有测试,对吧?

但是使用 | 意味着字符串 BCA6C22pAAAAAA 的部分匹配,因为它出现在 P 之后,即使第一个断言不正确,因为它不是以 C.

开头

不应该是这样的。我希望它仅在开头解释的所有条件都为真时才匹配。

有人可以向我解释为什么我的第一次尝试没有产生我想要的结果吗?另外,如何改进我的正则表达式?

我仍然需要它:

谢谢

您的主要问题是您正在使用 (?<=[pP]) 后视来了解前方的情况,这将永远行不通:您需要向前看 (?=...) .

此外,最后的量词应该是 + 而不是 *,因为您需要 p 之后至少有一个 个尾随字符。

最后一个错误是你没有捕获任何东西,你只是在匹配,所以把你想捕获的东西放在括号里,这也意味着你可以删除所有环顾四周。

如果您使用不区分大小写的标志,它会使正则表达式更小且更易于阅读。

捕获第 1 组和第 2 组中的 2 个十六进制部分的工作正则表达式是:

(?i)^c([a-f1-9]*)p([a-f1-9]+)

参见 live demo

除非你需要使用\A,否则更喜欢^(输入开始)而不是\A(多输入中所有输入的开始) line scenario) 因为 ^ 更容易阅读并且 \A 不会匹配每一行,这是许多情况和工具所期望的。我用过 ^.

匹配Pp

前后的两组
(?<=^[Cc])[1-9a-fA-F]+(?=[Pp]([1-9a-fA-F]+$))
  • (?<=^[Cc]) - 正面回顾。必须在行首匹配不区分大小写的 Cc
  • [1-9a-fA-F]+ - 匹配十六进制字符一次或多次
  • (?=[Pp] - 不区分大小写的正先行 pP
  • ([1-9a-fA-F]+$) - pP 后一个或多个十六进制字符的字符组 View Demo