RegEx для цен? - PullRequest
       37

RegEx для цен?

6 голосов
/ 10 октября 2009

Я ищу RegEx для цен. Таким образом, это должно быть число X перед, чем "," и в конце 2 числа максимум.

Может кто-нибудь поддержать меня и выложить, пожалуйста?

Ответы [ 13 ]

18 голосов
/ 10 октября 2009

На каком языке вы собираетесь его использовать?

Это должно быть что-то вроде:

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

Explaination:

Число X перед : ^\d+, где ^ означает начало строки, \d означает цифру, а + означает один или несколько

Мы используем группу () с вопросительным знаком, a ? означает: соответствует тому, что находится внутри группы, один раз или ни разу.

внутри группы есть ,\d{1,2}, , - запятая, которую вы написали, \d - все еще цифра {1,2} означает совпадение с предыдущей цифрой один или два раза.

Финал $ соответствует концу строки.

12 голосов
/ 17 августа 2015

Я не был удовлетворен предыдущими ответами. Вот мой взгляд на это:

\d{1,3}(?:[.,]\d{3})*(?:[.,]\d{2})

|^^^^^^|^^^^^^^^^^^^^|^^^^^^^^^^^|
| 1-3  | 3 digits    | 2 digits  |
|digits| repeat any  |           |
|      | no. of      |           |
|      | times       |           |

(подробное объяснение здесь: https://regex101.com/r/cG6iO8/1)

Охватывает все случаи ниже

  • 5,00
  • 1000
  • 1,000,000.99
  • 5,99 (европейская цена)
  • 5,999,99 (европейская цена)
  • 0,11
  • 0,00

Но и такие странные вещи, как

  • 5.000,000.00

В случае, если вы хотите включить 5 и 1000 (лично мне не нравится совпадать со ВСЕМИ числами), просто добавьте «?» вот так:

\d{1,3}(?:[.,]\d{3})*(?:[.,]\d{2})?
6 голосов
/ 25 августа 2015

Я работаю над аналогичной проблемой. Однако я хочу, чтобы совпадение только в том случае, если символ или строка валюты также включены в строку, как EUR, €, USD или $. Символ может быть ведомым или ведущим. Меня не волнует, есть ли пробел между подстрокой Number и Currency. Я основал сравнение чисел на предыдущем обсуждении и использовал номер цены: \ d {1,3} (?: [.,] \ D {3}) * (?: [.,] \ D {2})?

Вот окончательный результат:

(USD|EUR|€|\$)\s?(\d{1,3}(?:[.,]\d{3})*(?:[.,]\d{2}))|(\d{1,3}(?:[.,]\d{3})*(?:[.,]\d{2})?)\s?(USD|EUR|€|\$)

Я использую (\d{1,3}(?:[.,]\d{3})*(?:[.,]\d{2})?)\s?(USD|EUR|€|\$) в качестве шаблона для сопоставления с символом валюты (здесь с допуском для начального пробела). Я думаю, что вы можете легко настроить его для любых других валют

Gist с последней версией можно найти по адресу https://gist.github.com/wischweh/b6c0ac878913cca8b1ba

4 голосов
/ 23 апреля 2013

Итак, я столкнулся с подобной проблемой: мне нужно было проверить, является ли произвольная строка ценой, но нужно было гораздо больше устойчивости, чем регулярных выражений, представленных в этом и многих других потоках.

Мне нужно регулярное выражение, которое будет соответствовать всем следующим:

  • 5
  • 5,00
  • 1000
  • 1,000,000.99
  • 5,99 (европейская цена)
  • 5,999,99 (европейская цена)
  • 0,11
  • 0,00

И не сопоставлять такие вещи, как IP-адреса. Я не мог найти ни одного регулярного выражения для работы с европейскими и неевропейскими вещами одним махом, поэтому я написал немного кода Ruby для нормализации цен:

if value =~ /^([1-9][0-9]{,2}(,[0-9]{3})*|[0-9]+)(\.[0-9]{1,9})?$/
  Float(value.delete(","))
elsif value =~ /^([1-9][0-9]{,2}(\.[0-9]{3})*|[0-9]+)(,[0-9]{1,9})?$/
  Float(value.delete(".").gsub(",", "."))
else
  false
end

Единственное различие между двумя регулярными выражениями - это поменялись местами после запятой и запятой. Я попытаюсь объяснить, что это делает:

/^([1-9][0-9]{,2}(,[0-9]{3})*|[0-9]+)(\.[0-9]{1,9})?$/

Первая часть:

([1-9][0-9]{,2}(,[0-9]{3})*

Это заявление о числах, которые следуют за этой формой: 1 000 000 000 100 12. Но это не допускает начальных нулей. Это для правильно отформатированных чисел, которые имеют группы из 3 чисел, разделенных разделителем тысяч.

Вторая часть:

[0-9]+

Просто сопоставьте любое число 1 или более раз. Вы можете сделать это 0 или более раз, если хотите соответствовать: .11 .34 .00 и т. Д.

Последняя часть:

(\.[0-9]{1,9})?

Это бит десятичного разряда. Вы спрашиваете, почему до 9 чисел? Я видел, как это случилось. Предполагается, что это регулярное выражение будет в состоянии справиться с любой странной и замечательной ценой, которую он видит, и я видел, как некоторые розничные продавцы используют до 9 знаков после запятой в ценах. Обычно все 0, но мы не хотели бы пропустить данные ^ _ ^

Надеюсь, это поможет следующему человеку, которому понадобится обработать произвольно неправильно отформатированные строки цен или европейский или неевропейский формат:)

3 голосов
/ 10 октября 2009
^\d+,\d{1,2}$
1 голос
/ 17 декабря 2014

В настоящее время я работаю над небольшой функцией, использующей регулярное выражение для получения суммы цены внутри строки:

private static String getPrice(String input)
{
    String output = "";

    Pattern pattern = Pattern.compile("\\d{1,3}[,\\.]?(\\d{1,2})?");
    Matcher matcher = pattern.matcher(input);
    if (matcher.find())
    {
        output = matcher.group(0);
    }

    return output;
}

это похоже на небольшую цену (от 0,00 до 999,99) и различные валюты:

$ 12,34 -> 12,34

$ 12,34 -> 12,34

12,00 $ -> 12,00

$ 12 -> 12

12 € -> 12

12,11 € -> 12,11

12,999 € -> 12,99

12,9 € -> 12,9

£ 999,99 € -> 999,99

...

0 голосов
/ 25 марта 2019

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

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

matches:
    1,123,456,789,134.45
    1123456134.45
    1234568979
    12,345.45
    123.45
    123
no match:
    1,2,3
    12.4
    1234,456.45

Для корректной работы может потребоваться некоторое редактирование

Краткое объяснение: соответствует 1-3 числам (или ничему), соответствует запятой, за которой следуют 3 числа столько раз, сколько необходимо (или только числа), соответствует десятичной запятой, за которой следуют 1 или 2 числа (или ничего)

0 голосов
/ 21 августа 2016

Это разумно работает, когда вы можете иметь или не иметь десятичную часть, но сумма отображается как 100 000 - или 100 000,00. Протестировано только с использованием Clojure

\ d {1,3} (?: [.,] \ Д {3}) * (?: [.,] \ Д {2,3})

0 голосов
/ 25 декабря 2015

Пока что пробовал, это лучшее

\d{1,3}[,\\.]?(\\d{1,2})?

https://regex101.com/r/xT8aQ7/1

0 голосов
/ 18 сентября 2015

Этот код работал для меня! (PHP)

preg_match_all('/\d+((,\d+)+)?(.\d+)?(.\d+)?(,\d+)?/',$price[1]->plaintext,$lPrices);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...