如何匹配'K'、'M'、'G'、'Ki'、'Mi'、'Gi'等而不是单独的'i'词缀

How to match 'K', 'M', 'G', 'Ki', 'Mi', 'Gi' etc. but not solitary 'i' affix

我想要做的是将 shorthand 符号与 ISO 前缀(1k = 1000-1ki = -1024 等)相匹配。这个正则表达式很接近:

^([+-]?)(\d+)((?i)[KMGTPEZY]?(?i)i?$)

但它匹配 1i,所以我试图找到一个正则表达式,如果它前面有字符 class 中的一个字母,它只会匹配 i。我尝试使用后视:

^([+-]?)(\d+)((?i)[KMGTPEZY]?(?<=(?i)[KMGTPEZY])(?i)i?$)

这不会匹配 1i,但现在它不会匹配像 1 这样没有前缀的数字,而且似乎...不雅必须重复 [=25] =] 所以我希望有一种更优雅的方式来做到这一点......也适用于 Python :-).

如果它影响答案,完整的问题是我想处理像 123[5-10)、[=30= 这样的事情],1k-2k,2Mi-3Gi,10T...用适当的数字替换前缀 shorthand(1k=100010ki=10240 等)和然后生成实际序列的列表(因此将 [5-10) 扩展为 5,6,7,8,920-25 相当于 [20-25]20,21,22,23,24,25),但现在,我是在第一步,它只是匹配前缀 shorthand 表示法。

是的,也许可以用奇特的功能来解决这个问题。 但是不,没有必要。

简单的交替就足够了。

^([+-]?\d+)([KMGTPEZY]i|[KMGTPEZY]|)$

也就是说,例如,我们想要匹配 'Ki',或匹配 'K',或匹配...

这其实很简单:

(?i)^([+-])?(\d+)([KMGTPEZY]i?)?$

此处我们指定一个可选组 ([KMGTPEZY]i?)?,它本身包含可选匹配项 i?

请注意,作为全局标志,(?i) 只需指定一次(传统上指定在正则表达式的开头,很容易被发现)。如果你想指定后缀 的可选 i 部分 区分大小写,全局标志对你没有帮助,你必须这样做:

^([+-])?(\d+)([KkMmGgTtPpEeZzYy]i?)?$

示例:

>>> import re
>>> pattern = re.compile('(?i)^([+-])?(\d+)([KMGTPEZY]i?)?$')

>>> pattern.search('12').groups()
(None, '12', None)

>>> pattern.search('-34').groups()
('-', '34', None)

>>> pattern.search('+56m').groups()
('+', '56', 'm')

>>> pattern.search('-78ki').groups()
('-', '78', 'ki')

>>> pattern.search('90i').groups()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'groups'