我正在正则表达式中学习lookahead
和lookbehind
,并尝试将逗号应用于每3位数之间的数字。我被困在这里:
text = "The population of India is 1300598526 and growing."
pattern = re.compile(r'\b(?<=\d)(?=(\d\d\d)+\b)')
line = re.sub(pattern, r',', text)
print(line)
预期输出:
"The population of India is 1,300,598,526 and growing"
实际输出None
。模式不匹配。我尝试摆弄该模式,发现前导\b
是罪魁祸首。没有该模式,该模式就可以正常工作。为什么呢?请说清楚。
我更想知道上述模式中的错误,而不是重新设计的模式来实现相同的目的。谢谢。
答案 0 :(得分:1)
您的正则表达式以\b(?<=\d)
开头,并使用word boundary。该位置仅在1300598526
的末尾匹配。数字之间的单词边界不匹配,因此(?=(\d\d\d)+\b)
之后的部分不匹配。
解决这种不在单词内的转换数字的方法可能是在空格上分割以获取单词。然后,对每个项目进行映射,并检查是否包含4个或更多数字\A\d{4,}\Z
,并使用以下三个数字添加逗号:
\d(?=(?:\d{3})+(?!\d))
说明
\d
匹配数字(?=
积极肯定地断言右边是
(?:\d{3})+
重复一组3位数字(?!\d)
负向断言来断言右边的不是数字)
积极回望例如:
import re
text = "The population 12test1234 of India is 1300598526 and growing."
pattern = re.compile(r"\d(?=(?:\d{3})+(?!\d))")
subst = r"\g<0>,"
res = map(lambda x: re.sub(pattern, subst, x) if re.match(r"\A\d{4,}\Z", x) else x, text.split(' '))
print (" ".join(res))
结果
The population 12test1234 of India is 1,300,598,526 and growing.
请参见Regex demo | Python demo