使用正则表达式将数字从右到左分成三组

时间:2017-08-30 01:21:25

标签: regex python-3.x regex-lookarounds

我有一个字符串'1234567890',我希望从右到左分成三组三组,最左边的组从一位到三位(取决于剩余的位数)

基本上,它与向长号添加逗号的过程相同,除此之外,我还想提取最后三位数字。

我尝试使用环视但无法找到获得最后三个的方法 数字。

string = '1234567890'
re.compile(r'\d{1,3}(?=(?:\d{3})+$)')
re.findall(pattern, string)

['1', '234', '567']

预期输出是(我不需要逗号):

 ['1', '234', '567', 789]

3 个答案:

答案 0 :(得分:2)

欣赏如果我们从右到左添加逗号,对于每组三个完整数字,那么我们可以简单地用正则表达式替换所有三个数字,这三个数字后跟一个逗号。在下面的代码片段中,我反转数字字符串,执行逗号工作,然后再次反转以达到我们想要的输出。

string = '1234567890'
string = re.sub(r'(?=\d{4})(\d{3})', r'\1,', string[::-1])[::-1]
print string.split(',')
string = '123456789'
string = re.sub(r'(?=\d{4})(\d{3})', r'\1,', string[::-1])[::-1]
print string.split(',')

<强>输出:

['1', '234', '567', '890']
['123', '456', '789']

用于替换的正则表达式的一部分可能需要进一步解释。我在模式的开头添加了一个正向前瞻(?=\d{4})。这是为了确保我们在最后一组三位数之后添加逗号。

在这里演示:

Rextester

答案 1 :(得分:2)

实际上更容易对反向字符串进行操作以跟踪有更多数字的3位数字组((?=\d)的正向前瞻:

for s in ('123','1234','123456789','1234567890'):
    print(re.sub(r'(\d\d\d)(?=\d)',r'\1,',s[::-1])[::-1])

或否定前瞻版本:

for s in ('123','1234','123456789','1234567890'):
    print(re.sub(r'(\d\d\d)(?!$)',r'\1,',s[::-1])[::-1])

打印:

123
1,234
123,456,789
1,234,567,890

在反向字符串上应用反向正则表达式在Perl中称为sexeger; - )

您还可以执行不需要反转字符串的超前版本:

for s in ('123','1234','123456789','1234567890'):
   print(re.sub(r'(\d)(?=(\d{3})+$)',r'\1,',s))
# same output

根据评论,只需添加一个合适的分隔符,然后添加.split

>>> for s in ('123','1234','123456789','1234567890'):
...     re.sub(r'(\d)(?=(\d{3})+$)',r'\1\t',s).split('\t')
... 
['123']
['1', '234']
['123', '456', '789']
['1', '234', '567', '890']

或者,跳过正则表达式并在Python中执行:

for s in ('123','1234','123456789','1234567890'):
    s=s[::-1]
    n=3
    print([s[i:i+n][::-1] for i in range(0,len(s),n)][::-1])
# same output

答案 2 :(得分:0)

您非常亲密。问题是,当您位于最后一组时,前瞻子表达式中的+将使整个表达式失败,因为将没有1到3位数字的组,后面是至少一组3位数字数字(前瞻子表达式指定的数字)。

考虑一下使用123时会发生什么。仅当出现1到3位数字的组,然后是至少一个 3位数字的组时,您的表达式才会匹配。在这种情况下不会发生这种情况,因为3位数字123的组后面没有任何内容,因此表达式将失败,并且该组将不包含在输出中。

只需将+更改为*就可以解决此问题,因为在当前的1到3位数字组之后不需要有3位数字组:

>>> pattern = re.compile(r'\d{1,3}(?=(?:\d{3})*$)')
>>> pattern.findall('1')
['1']
>>> pattern.findall('123')
['123']
>>> pattern.findall('1234')
['1', '234']
>>> pattern.findall('123456789')
['123', '456', '789']
>>> pattern.findall('1234567890')
['1', '234', '567', '890']
>>> pattern.findall('')
[]