簡體   English   中英

使用點或逗號作為分隔符的帶或不帶小數的數字的 Python 正則表達式?

[英]Python regex for number with or without decimals using a dot or comma as separator?

我只是在學習正則表達式,現在我正在嘗試匹配一個或多或少代表這個的數字:

[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 並且我的正則表達式不正確。 有人能告訴我我做錯了什么嗎? 歡迎所有提示!

你需要讓[.,]通過增加部分為可選? 在那個字符類之后,也不要忘記添加錨點。 ^斷言我們在開始, $斷言我們在結束。

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

演示

>>> 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*$

演示

如果您只在前面添加 ^ 並在后面添加 $ 以便系統知道您的字符串將如何開始和結束,您的正則表達式將正常工作。

嘗試這個

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

問題是您要求部分匹配,只要它從頭開始。

解決此問題的一種方法是在\\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是 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

怎么樣:

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

如果您不想要空字符串:

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

試試這個。驗證所有案例。見演示。

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

驗證非空匹配的一些想法:

1.) 使用先行檢查至少一位數字:

^(?=.?\d)\d*[.,]?\d*$
  • ^開始$結束
  • (?=.?\\d)匹配如果,1 , 1 ,...
  • \\d*[.,]?\\d*允許的序列: \\d*任意數量的數字,后跟一個[.,] , \\d*
  • 請注意,第一個. 前瞻內部是一個元字符,代表任何字符,而字符類[.,]中的另一個與文字匹配.

也可以使用負前瞻代替正前瞻: ^(?!\\D*$)\\d*[.,]?\\d*$

在 regex101 測試Regex FAQ


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

^(?:\d+[.,]\d*|[.,]?\d+)$
  • (?:為交替啟動一個非捕獲組
  • \\d+[.,]\\d*用於匹配1. , 1,1 ,... | 或者
  • [.,]?\\d+用於匹配1 , ,1 ...

在 regex101 測試

如果兩個小數位是強制性的,您可以使用以下內容:

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

更通用的方法可以如下

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

這將匹配以下模式:

  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。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM