Множество вещей неправильны в вашем выражении:
^\{USD}?(\d*(\d\.?|\.\d{1,2}))$
\{USD}?
в языке регулярных выражений это будет означать: ожидать буквального символа {
, за которым следует USD
, за которым следует символ }
, если таковой имеется. Если вы хотите иметь необязательную группу USD
, вы должны использовать круглые скобки без \
: (USD)?
. Для этого вы можете использовать группу без захвата : (?:USD)?
.
Это даст: ^(USD)?(\d*(\d\.?|\.\d{1,2}))$
(\d\.?|\.\d{1,2})
, вся группа должна быть повторена, чтобы соответствовать всей строке: (\d\.?|\.\d{1,2})*
Это даст: ^(USD)?(\d*(\d\.?|\.\d{1,2})*)$
\d\.?
: если предполагается, что часть соответствует разделителю тысяч, это должна быть запятая, а не точка в вашем примере: \d*,?
Это даст: ^(USD)?(\d*(\d,?|\.\d{1,2})*)$
(\d*(\d
: это не сработает, второе \d
никогда не будет совпадать, поскольку все цифры будут использованы первым \d*
, вы можете использовать не жадный оператор ?
, например: (\d*?(\d
но это не красиво.
Это даст: ^(USD)?(\d*?(\d,?|\.\d{1,2})*)$
, что может сработать для вас, но выглядит неоптимально.
Альтернативой может быть создание регулярного выражения без предложения "или" с использованием следующих частей:
- Префикс: "USD", необязательный и с дополнительным пробелом:
(USD ?)?
- Неотъемлемая часть суммы перед тысячей разделителей:
\d+
- Неотъемлемая часть суммы с разделителем тысяч, необязательная и повторяемая:
(,\d+)*
- Десятичная часть, необязательно:
(\.\d+)?
Который дал бы что-то подобное: (USD ?)?(\d+)(,\d+)*(\.\d+)?
Вы можете проверить это на regex101.com
Вы можете дополнительно ограничить количество цифр в каждой части, чтобы избежать ложноположительного результата:
(USD ?)?(\d{1,3})(,\d{3})*(\.\d{1,2})?
Окончательная версия будет оптимизирована с не захватывающими группами , если это не необходимо:
(?:USD ?)?(?:\d{1,3})(?:,\d{3})*(?:\.\d{1,2})?
Редактировать: предоставленный вами тестовый пример использует некогерентное использование десятичных разделителей (иногда ".", Иногда ","). Если вы действительно хотите соответствовать этому, вы можете использовать класс символов следующим образом:
(?:USD ?)?(?:\d{1,3})(?:,\d{3})*(?:[.,]\d{1,2})?
Что соответствует каждому числу в вашем примере:
