使用点或逗号作为分隔符,使用或不使用小数的Python正则表达式?

时间:2014-10-01 09:15:31

标签: python regex

我正在学习正则表达式,现在我正试图匹配一个或多或少代表这个数字的数字:

[zero or more numbers][possibly a dot or comma][zero or more numbers]

没有点或逗号也没关系。所以它应该匹配以下内容:

1
123
123.
123.4
123.456
.456
123,  # From here it's the same but with commas instead of dot separators
123,4
123,456
,456

但它不符合以下条件:

0.,1
0a,1
0..1
1.1.2
100,000.99  # I know this and the one below are valid in many languages, but I simply want to reject these
100.000,99

到目前为止,我已经提出了[0-9]*[.,][0-9]*,但它似乎没有那么好用:

>>> import re
>>> r = re.compile("[0-9]*[.,][0-9]*")
>>> if r.match('0.1.'): print 'it matches!'
...
it matches!
>>> if r.match('0.abc'): print 'it matches!'
...
it matches!

我感觉我做错了两件事:我没有正确使用匹配且我的正则表达式不正确。有人可以告诉我我做错了什么吗?欢迎所有提示!

8 个答案:

答案 0 :(得分:9)

您需要在该角色类之后添加[.,]并将?部分作为选项,并且不要忘记添加锚点。 ^声称我们处在起点,$声称我们已经结束了。

^\d*[.,]?\d*$

DEMO

>>> import re
>>> r = re.compile(r"^\d*[.,]?\d*$")
>>> if r.match('0.1.'): print 'it matches!'
... 
>>> if r.match('0.abc'): print 'it matches!'
... 
>>> if r.match('0.'): print 'it matches!'
... 
it matches!

如果您不想允许使用单个逗号或点,请使用前瞻。

^(?=.*?\d)\d*[.,]?\d*$

DEMO

答案 1 :(得分:2)

问题在于你要求部分匹配,只要它从头开始。

解决此问题的一种方法是在\Z中结束正则表达式(可选$)。

  

\Z仅匹配字符串的末尾。

另一种是使用re.fullmatch代替。

import re
help(re.match)
#>>> Help on function match in module re:
#>>>
#>>> match(pattern, string, flags=0)
#>>>     Try to apply the pattern at the start of the string, returning
#>>>     a match object, or None if no match was found.
#>>>

VS

import re
help(re.fullmatch)
#>>> Help on function fullmatch in module re:
#>>>
#>>> fullmatch(pattern, string, flags=0)
#>>>     Try to apply the pattern to all of the string, returning
#>>>     a match object, or None if no match was found.
#>>>

请注意,fullmatch是3.4中的新内容。

您还应该将[.,]部分设为可选部分,因此请附加?

  

'?'使得到的RE匹配前面RE的0或1次重​​复。 AB?将匹配'a'或'ab'。

例如

import re
r = re.compile("[0-9]*[.,]?[0-9]*\Z")

bool(r.match('0.1.'))
#>>> False

bool(r.match('0.abc'))
#>>> False

bool(r.match('0123'))
#>>> True

答案 2 :(得分:2)

如果你只是在前面添加^而在后面添加$,你的正则表达式会正常工作,这样系统就知道你的字符串将如何开始和结束。

试试这个

^[0-9]*[.,]{0,1}[0-9]*$

import re

checklist = ['1', '123', '123.', '123.4', '123.456', '.456', '123,', '123,4', '123,456', ',456', '0.,1', '0a,1', '0..1', '1.1.2', '100,000.99', '100.000,99', '0.1.', '0.abc']

pat = re.compile(r'^[0-9]*[.,]{0,1}[0-9]*$')

for c in checklist:
   if pat.match(c):
      print '%s : it matches' % (c)
   else:
      print '%s : it does not match' % (c)

1 : it matches
123 : it matches
123. : it matches
123.4 : it matches
123.456 : it matches
.456 : it matches
123, : it matches
123,4 : it matches
123,456 : it matches
,456 : it matches
0.,1 : it does not match
0a,1 : it does not match
0..1 : it does not match
1.1.2 : it does not match
100,000.99 : it does not match
100.000,99 : it does not match
0.1. : it does not match
0.abc : it does not match

答案 3 :(得分:1)

怎么样:

(?:^|[^\d,.])\d*(?:[,.]\d+)?(?:$|[^\d,.])

如果你不想要空字符串:

(?:^|[^\d,.])\d+(?:[,.]\d+)?(?:$|[^\d,.])

答案 4 :(得分:1)

^(?=.?\d)(?!(.*?\.){2,})[\d.]+$|^(?=.?\d)(?!(.*?,){2,})[\d,]+$

试试这个。验证所有情况。参见演示。

http://regex101.com/r/hS3dT7/9

答案 5 :(得分:1)

验证非空匹配的一些想法:

1。)使用lookahead检查至少一位数字:

^(?=.?\d)\d*[.,]?\d*$
  • ^ start$ end
  • (?=.?\d)匹配,11,...
  • \d*[.,]?\d*允许的顺序:\d*任意数量的数字,后跟一个[.,]\d*
  • 请注意,前瞻中的第一个.metacharacter代表任何字符,而另一个代表character class {{1} }匹配文字[.,]

也可以使用否定的前瞻性代替前瞻性:.

Test at regex101Regex FAQ


2.)使用2种不同的模式:

^(?!\D*$)\d*[.,]?\d*$
  • ^(?:\d+[.,]\d*|[.,]?\d+)$ 为替换开始non-capture group
  • (?:匹配\d+[.,]\d*1.,... 1,1
  • |用于匹配[.,]?\d+1 ...

Test at regex101

答案 6 :(得分:0)

如果必须将小数点后两位放在首位,则可以使用以下代码:

^((\d){1,3},*){1,5}\.(\d){2}$

这将与以下模式匹配:

  • 1.00
  • 10.00
  • 100.00
  • 1,000.00
  • 10,000.00
  • 100,000.00
  • 1,000,000.00

答案 7 :(得分:0)

更多通用方法如下

{{1}}

这将与以下模式匹配:

  1. 这将与以下模式匹配:
    • 100
    • 1,000
    • 100.00
    • 1,000.00
    • 1,00,000
    • 1,00,000.00
  2. 这将匹配以下模式:

    • .100
    • .. 100
    • 100.100.00
    • 100
    • 100,
    • 100。