有人能解释一下money regex,它只检查值是否与某个模式匹配吗?

2024-03-28 10:46:37 发布

您现在位置:Python中文网/ 问答频道 /正文

这里有多个帖子捕获了值,但我只是想看看值是不是什么东西。更模糊地说,我想了解检查一个值和“捕获”一个值之间的区别。在当前情况下,价值应为以下可接受的货币格式:

Here is a post这解释了一些关于money regex的事情,但我一点也不明白。

.50
50
50.00
50.0
$5000.00
$.50

我不想要逗号(人们应该知道这很荒谬)。

我遇到的麻烦是:

  1. 允许在值开始时使用$(但仍然是可选的)
  2. 只允许1个小数点(但不允许在末尾)
  3. 了解它是如何在内部工作的
  4. 同时了解如何从中得到一个规范化的版本(只有数字和可选的小数点),去掉美元符号。

我现在的regex(显然不工作)是:

# I'm checking the Boolean of the following:
re.compile(r'^[\$][\d\.]$').search(value)

(注:我在Python中工作)


Tags: thehereis格式货币事情post帖子
3条回答

Also understanding out to get a normalized version (only digits and a the optional decimal point) out of it that strips the dollar sign.

这也被称为“捕获”值;)

制作亚伦的基本示例:

/^\$?(\d+(?:\.\d{1,2})?)$/

然后金额(不带美元符号)将在捕获组1中。

这是一个你可以使用的正则表达式:

regex = re.compile(r'^\$?(\d*(\d\.?|\.\d{1,2}))$')

这是我用来测试的试验台。我包括了你所有的测试,还有我自己的一些。我还包括了一些负面的测试,因为确保它在不应该匹配的时候不匹配和确保它在应该匹配的时候匹配一样重要。

tests = [
    ('.50', True),
    ('50', True),
    ('50.00', True),
    ('50.0', True),
    ('$5000', True),
    ('$.50', True),
    ('$5.', True),
    ('$5.000', False),
    ('5000$', False),
    ('$5.00$', False),
    ('$-5.00', False),
    ('$5,00', False),
    ('', False),
    ('$', False),
    ('.', False),
]

import re
regex = re.compile(r'^\$?(\d*(\d\.?|\.\d{1,2}))$')
for test, expected in tests:
    result = regex.match(test) 
    is_match = result is not None
    print test + '\t' + ('OK' if is_match == expected else 'Fail')

要获取不带$的值,可以使用捕获的组:

print result.group(1)

假设您希望允许$5.,但不允许5.,则以下语言将被接受:

money = re.compile('|'.join([
  r'^\$?(\d*\.\d{1,2})$',  # e.g., $.50, .50, $1.50, $.5, .5
  r'^\$?(\d+)$',           # e.g., $500, $5, 500, 5
  r'^\$(\d+\.?)$',         # e.g., $5.
]))

需要理解的重要内容:

  • ^$分别只在输入字符串的开头和结尾匹配。
  • \.匹配文本点
  • \$匹配文本美元符号
    • \$?匹配美元符号或不匹配(,可选美元符号)
  • \d匹配任何单个数字(0-9)
    • \d*匹配零个或多个数字的运行
    • \d+匹配一个或多个数字的运行
    • \d{1,2}匹配任何一个数字或两个数字的运行

带括号的子模式是捕获组:与捕获组中的子表达式匹配的输入中的所有文本都将在matchobj.group(index)中可用。美元符号不会被捕获,因为它在括号外。

因为Python不支持多个同名的捕获组(!!!)我们必须在matchobj.groups()中搜索不在None中的那个。这也意味着您在修改模式以对除数量之外的每个组使用(?:...)时必须小心。

调整马克的测试套,我们得到

for test, expected in tests:
    result = money.match(test) 
    is_match = result is not None
    if is_match == expected:
      status = 'OK'
      if result:
        amt = [x for x in result.groups() if x is not None].pop()
        status += ' (%s)' % amt
    else:
      status = 'Fail'
    print test + '\t' + status

输出:

.50     OK (.50)
50      OK (50)
50.00   OK (50.00)
50.0    OK (50.0)
$5000   OK (5000)
$.50    OK (.50)
$5.     OK (5.)
5.      OK
$5.000  OK
5000$   OK
$5.00$  OK
$-5.00  OK
$5,00   OK
        OK
$       OK
.       OK
.5      OK (.5)

相关问题 更多 >