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

jdzmm42g  于 2023-03-04  发布在  Python
关注(0)|答案(9)|浏览(187)

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

[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!

我觉得我做错了两件事:我没有正确使用match,我的正则表达式也不正确。有人能告诉我我做错了什么吗?欢迎提供所有的建议!

bvpmtnay

bvpmtnay1#

你需要通过在字符类后面添加?来使[.,]成为可选的,并且不要忘记添加锚。^Assert我们在开始处,$Assert我们在结束处。

^\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

bvjveswy

bvjveswy2#

如果你只在前面加上^,在后面加上$,这样系统就知道你的字符串是如何开始和结束的,那么正则表达式就能正常工作。
试试这个

^[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
ecfdbz9o

ecfdbz9o3#

问题是您要求的是部分匹配,只要它从头开始。
解决这个问题的一种方法是以\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.
#>>>

对比

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是Python 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
nqwrtyyt

nqwrtyyt4#

不如这样:

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

如果您不希望使用空字符串:

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

bnl4lu3b5#

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

试试这个。验证所有案例。看演示。
http://regex101.com/r/hS3dT7/9

vlju58qv

vlju58qv6#

验证非空匹配的一些想法:
1.)使用lookahead检查是否至少有一个数字:

^(?=.?\d)\d*[.,]?\d*$
  • 从一月一日到一月一日到一月二日。
  • 如果,11、...,则(?=.?\d)匹配
  • \d*[.,]?\d*允许的序列:\d*任意位数,后跟一个[.,]\d*
  • 请注意,lookahead中的第一个.metacharacter,它代表 * 任意字符 *,而character class[.,]中的另一个.匹配文字.

也可以使用负前瞻来代替正前瞻:^(?!\D*$)\d*[.,]?\d*$
Test at regex101、正则表达式常见问题解答
2.)使用2种不同的模式:

^(?:\d+[.,]\d*|[.,]?\d+)$
  • (?:启动一个non-capture group进行交替。
  • \d+[.,]\d*用于匹配1.1,1、... |
  • 用于匹配1,1 ...

Test at regex101

7xllpg7q

7xllpg7q7#

如果两位小数是强制性的,您可以使用以下格式:

^((\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
wj8zmpe1

wj8zmpe18#

更通用的方法可以如下

import re
r=re.compile(r"^\d\d*[,]?\d*[,]?\d*[.,]?\d*\d$")
print(bool(r.match('100,000.00')))

这将匹配以下模式:

  • 这将匹配以下模式:
  • 100
  • 1,000
  • 100.00
  • 1,000.00
  • 1,00,000
  • 1,00,000.00
  • 这将匹配以下模式:
  • .100
  • ..100
  • 100.100.00
  • ,100
  • 100,
7kjnsjlb

7kjnsjlb9#

好的,我用来检查整数是否有千位分隔符的正则表达式,可能包含也可能不包含小数部分,然后是一个没有小数部分的正则表达式,如下所示:
(this是python 3.10.8我正在使用,不知道哪个版本regex,though.)
r”^(?:-)?(\d{1,3}(?:(?:.(?=\d.+\,?)|\,(?=\d.+.?))\d{3})*(.\d+)?|\d+.\d+|\d+)$”
希望这能帮上忙。

相关问题