从两个字符之间提取两个字符串。为什么我的正则表达式不匹配,我该如何改进它?
Extracting two strings from between two characters. Why doesn't my regex match and how can I improve it?
我正在学习正则表达式,我想从具有以下特征的文本中提取一个字符串:
- 它总是以字母
C
开头,无论是小写还是
大写字母,然后是一些十六进制数
字符(意味着它可以包含字母 A to F
和数字
来自 1 to 9
,不包括零)。
- 那些十六进制之后
characters comes a letter
P
, also in lowercase or uppercase
- 然后是更多的十六进制字符(同样,不包括 0)。
意思是我想捕获字母 C
和 P
之间的字符串以及字母 P
之后的字符串并将它们连接成一个字符串,同时丢弃字母 C
和 P
有效字符串的示例为:
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,我想要一个正则表达式来提取字符 C
和 P
之间以及 [=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 它找到的第一个匹配项。其余的表达式没有测试,对吧?
但是使用 |
意味着字符串 BCA6C22pAAA
是 AAA
的部分匹配,因为它出现在 P
之后,即使第一个断言不正确,因为它不是以 C
.
开头
不应该是这样的。我希望它仅在开头解释的所有条件都为真时才匹配。
有人可以向我解释为什么我的第一次尝试没有产生我想要的结果吗?另外,如何改进我的正则表达式?
我仍然需要它:
- 如果字符串包含数字 0,则不匹配
- 只有满足所有条件才匹配
谢谢
您的主要问题是您正在使用 (?<=[pP])
后视来了解前方的情况,这将永远行不通:您需要向前看 (?=...)
.
此外,最后的量词应该是 +
而不是 *
,因为您需要 在 p
之后至少有一个 个尾随字符。
最后一个错误是你没有捕获任何东西,你只是在匹配,所以把你想捕获的东西放在括号里,这也意味着你可以删除所有环顾四周。
如果您使用不区分大小写的标志,它会使正则表达式更小且更易于阅读。
捕获第 1 组和第 2 组中的 2 个十六进制部分的工作正则表达式是:
(?i)^c([a-f1-9]*)p([a-f1-9]+)
参见 live demo。
除非你需要使用\A
,否则更喜欢^
(输入开始)而不是\A
(多输入中所有输入的开始) line scenario) 因为 ^
更容易阅读并且 \A
不会匹配每一行,这是许多情况和工具所期望的。我用过 ^
.
匹配P
或p
前后的两组
(?<=^[Cc])[1-9a-fA-F]+(?=[Pp]([1-9a-fA-F]+$))
(?<=^[Cc])
- 正面回顾。必须在行首匹配不区分大小写的 C
或 c
[1-9a-fA-F]+
- 匹配十六进制字符一次或多次
(?=[Pp]
- 不区分大小写的正先行 p
或 P
([1-9a-fA-F]+$)
- pP
后一个或多个十六进制字符的字符组
View Demo
我正在学习正则表达式,我想从具有以下特征的文本中提取一个字符串:
- 它总是以字母
C
开头,无论是小写还是 大写字母,然后是一些十六进制数 字符(意味着它可以包含字母A to F
和数字 来自1 to 9
,不包括零)。 - 那些十六进制之后
characters comes a letter
P
, also in lowercase or uppercase - 然后是更多的十六进制字符(同样,不包括 0)。
意思是我想捕获字母 C
和 P
之间的字符串以及字母 P
之后的字符串并将它们连接成一个字符串,同时丢弃字母 C
和 P
有效字符串的示例为:
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,我想要一个正则表达式来提取字符 C
和 P
之间以及 [=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 它找到的第一个匹配项。其余的表达式没有测试,对吧?
但是使用 |
意味着字符串 BCA6C22pAAA
是 AAA
的部分匹配,因为它出现在 P
之后,即使第一个断言不正确,因为它不是以 C
.
不应该是这样的。我希望它仅在开头解释的所有条件都为真时才匹配。
有人可以向我解释为什么我的第一次尝试没有产生我想要的结果吗?另外,如何改进我的正则表达式?
我仍然需要它:
- 如果字符串包含数字 0,则不匹配
- 只有满足所有条件才匹配
谢谢
您的主要问题是您正在使用 (?<=[pP])
后视来了解前方的情况,这将永远行不通:您需要向前看 (?=...)
.
此外,最后的量词应该是 +
而不是 *
,因为您需要 在 p
之后至少有一个 个尾随字符。
最后一个错误是你没有捕获任何东西,你只是在匹配,所以把你想捕获的东西放在括号里,这也意味着你可以删除所有环顾四周。
如果您使用不区分大小写的标志,它会使正则表达式更小且更易于阅读。
捕获第 1 组和第 2 组中的 2 个十六进制部分的工作正则表达式是:
(?i)^c([a-f1-9]*)p([a-f1-9]+)
参见 live demo。
除非你需要使用\A
,否则更喜欢^
(输入开始)而不是\A
(多输入中所有输入的开始) line scenario) 因为 ^
更容易阅读并且 \A
不会匹配每一行,这是许多情况和工具所期望的。我用过 ^
.
匹配P
或p
(?<=^[Cc])[1-9a-fA-F]+(?=[Pp]([1-9a-fA-F]+$))
(?<=^[Cc])
- 正面回顾。必须在行首匹配不区分大小写的C
或c
[1-9a-fA-F]+
- 匹配十六进制字符一次或多次(?=[Pp]
- 不区分大小写的正先行p
或P
([1-9a-fA-F]+$)
-pP
后一个或多个十六进制字符的字符组 View Demo