Кто-то может объяснить деньги regex, который просто проверяет, соответствует ли значение некоторому шаблону?

Существует несколько сообщений на здесь, что значение получения, но я просто надеюсь проверять, чтобы видеть, является ли значение чем-то. Более неопределенно помещенный; я надеюсь понимать различие между проверкой значения и "получением" значения. В текущем случае значение было бы следующими приемлемыми денежными форматами:

Вот сообщение, которое объясняет некоторых приблизительно деньги 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),

6
задан Community 23 May 2017 в 12:09
поделиться

4 ответа

Предположим, вы хотите разрешить $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.group() ту, которая не является 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)
15
ответ дан 8 December 2019 в 03:26
поделиться

Вот регулярное выражение, которое вы можете использовать:

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)
7
ответ дан 8 December 2019 в 03:26
поделиться

Это зависит от того, что вы подразумеваете под «одинаковыми значениями». Если вы хотите, чтобы строки были неравными друг к другу - а не только ссылки, то вам придется написать свой собственный , метод (myTuple) .

-121--4321104-

Также понимание, чтобы получить нормированную версию (только цифры и дополнительную десятичную точку) из него, которые полосывают знак доллара.

Это также известно как «захват» значение;)

Отработает базовый пример Aaron:

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

, тогда сумма (без знака доллара) будет в группе захвата 1.

4
ответ дан 8 December 2019 в 03:26
поделиться

Я считаю, что следующее Regex будет соответствовать вашим потребностям:

/^\$?(\d*(\.\d\d?)?|\d+)$/

Это позволяет для необязательного «$». Это позволяет для необязательного десятичного десятичного времени, но требует как минимум одного, но не более двух цифр после десятичного времени, если десятичное время присутствует.

Редактировать: Внешние скобки будут ловить все числовое значение для вас.

3
ответ дан 8 December 2019 в 03:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: