是否可以使用正则表达式找到一个用零填充的模式,并且 return 没有填充的值?
Is it possible to use regular expressions to find a pattern which is padded with zeros, and return the value without padding?
我有一个字母数字参考 ID 列表。他们有 3 个数字,左边用零填充,后面是一个字母,再后面是 3 个数字,同样,左边用零填充。
例如
original_ref_list = ["005a004",
"018b003",
"007a029",
"105a015"]
如您所见,两组数字都用零填充。我想获得相同的引用,但字母两边都没有零填充,但不想删除所有零。
例如
fixed_ref_list = ["5a4",
"18b3",
"7a29",
"105a15"]
我可以通过搜索三个正则表达式模式、组合结果并将其附加到列表中来做到这一点:
fixed_ref_list = list()
for i in original_ref_list:
first_refpat = re.compile(r'[1-9]\d*[a-z]\d+')
first_refpatiter = first_refpat.finditer(gloss[2])
for first_ref_find in first_refpatiter:
first_ref = first_ref_find.group()
second_refpat = re.compile(r'[a-z]\d+')
second_refpatiter = second_refpat.finditer(first_ref)
for second_ref_find in second_refpatiter:
second_ref = second_ref_find.group()[1:]
third_refpat = re.compile(r'[1-9]\d*')
third_refpatiter = third_refpat.finditer(second_ref)
for third_ref_find in third_refpatiter:
third_ref = third_ref_find.group()
fixed_ref_list.append(first_ref[:-len(second_ref)] + third_ref)
但这似乎是一个尴尬的解决方案。是否有一种内置方法可以仅 return 正则表达式模式的一部分,或者在 return 结果之前删除填充?或者,有没有什么方法可以做我想做的事情而不那么混乱?
您可以像这样使用括号对匹配项进行分组:
re.match('([0-9a-f]{3})([0-9a-f])([0-9a-f]{3})', '005a004').groups()
> ('005', 'a', '004')
现在你有一个元组可以使用了。要删除开头的零,可以使用 ^
运算符匹配所有的 0,它标记字符串的开头并将它们替换为空字符串 ''
:
re.sub('^0+', '', '004')
> '4'
这应该给你所有你需要的,使它更紧凑和可读。
使用列表理解
fixed_ref_list = [str(int(x[:3])) + x[3] + str(int(x[4:])) for x in original_ref_list]
结果
print(fixed_ref_list)
输出
["5a4",
"18b3",
"7a29",
"105a15"]
说明
假设零填充在数字 0-9 上,使用 int(...) 删除字段中的零填充
只需使用以下模式 "0+
并将其替换为 "
。参见 demo。
小心,因为你还没有说你希望最后一个案例发生什么here。
如果您想将完整的十六进制数 "00000"
替换为 "0"
,您有
"0*([0-9a-fA-F]+)"
如图here.
我有一个字母数字参考 ID 列表。他们有 3 个数字,左边用零填充,后面是一个字母,再后面是 3 个数字,同样,左边用零填充。
例如
original_ref_list = ["005a004",
"018b003",
"007a029",
"105a015"]
如您所见,两组数字都用零填充。我想获得相同的引用,但字母两边都没有零填充,但不想删除所有零。
例如
fixed_ref_list = ["5a4",
"18b3",
"7a29",
"105a15"]
我可以通过搜索三个正则表达式模式、组合结果并将其附加到列表中来做到这一点:
fixed_ref_list = list()
for i in original_ref_list:
first_refpat = re.compile(r'[1-9]\d*[a-z]\d+')
first_refpatiter = first_refpat.finditer(gloss[2])
for first_ref_find in first_refpatiter:
first_ref = first_ref_find.group()
second_refpat = re.compile(r'[a-z]\d+')
second_refpatiter = second_refpat.finditer(first_ref)
for second_ref_find in second_refpatiter:
second_ref = second_ref_find.group()[1:]
third_refpat = re.compile(r'[1-9]\d*')
third_refpatiter = third_refpat.finditer(second_ref)
for third_ref_find in third_refpatiter:
third_ref = third_ref_find.group()
fixed_ref_list.append(first_ref[:-len(second_ref)] + third_ref)
但这似乎是一个尴尬的解决方案。是否有一种内置方法可以仅 return 正则表达式模式的一部分,或者在 return 结果之前删除填充?或者,有没有什么方法可以做我想做的事情而不那么混乱?
您可以像这样使用括号对匹配项进行分组:
re.match('([0-9a-f]{3})([0-9a-f])([0-9a-f]{3})', '005a004').groups()
> ('005', 'a', '004')
现在你有一个元组可以使用了。要删除开头的零,可以使用 ^
运算符匹配所有的 0,它标记字符串的开头并将它们替换为空字符串 ''
:
re.sub('^0+', '', '004')
> '4'
这应该给你所有你需要的,使它更紧凑和可读。
使用列表理解
fixed_ref_list = [str(int(x[:3])) + x[3] + str(int(x[4:])) for x in original_ref_list]
结果
print(fixed_ref_list)
输出
["5a4",
"18b3",
"7a29",
"105a15"]
说明
假设零填充在数字 0-9 上,使用 int(...) 删除字段中的零填充
只需使用以下模式 "0+
并将其替换为 "
。参见 demo。
小心,因为你还没有说你希望最后一个案例发生什么here。
如果您想将完整的十六进制数 "00000"
替换为 "0"
,您有
"0*([0-9a-fA-F]+)"
如图here.