PHP регулярное выражение соответствует действительной зарплате, включая символы - PullRequest
2 голосов
/ 20 сентября 2019

Я пытаюсь проверить ввод для соответствия окладу или диапазону окладов - проблема в том, что пользователь может ввести несколько возможных значений.

Например, ниже допустимо:

2000
2,000
2000.00
2,000.00

2000 - 4000
2,000-4,000
2,000.00-4,000.00
$2,000.00-$4,000.00
£2,000.00-£4,000.00

Первоначально мы решили разрешить все, кроме букв, но это позволило бы что-то вроде 2! 000, что было бы недопустимым

На данный момент мы получили:

if (preg_match('/^\d|\d,\d+(\.(\d{2}))?$/', $i)) {
   return true;
}

Это работает для первых 4 примеров, но допускает такие вещи, как 2a000, что недопустимо - есть ли способ перечислить все, что строка не может содержать (буквы и символы, например, кроме валюты, точки и запятой), но все же затем сделатьсопоставление с образцом, чтобы мы могли проверять числа, например?

Ответы [ 4 ]

4 голосов
/ 20 сентября 2019

Вы можете захватить $ или £ в группе, а затем для согласованности использовать обратную ссылку для сопоставления того же символа во второй части (что необязательно).

Чтобы немного сократить шаблонВы можете использовать подпрограмму (?2), чтобы повторить сопоставление цифр в группе захвата 2.

^([$£]?)((?:\d{1,3}(?:,\d{3})*|\d+)\b(?:\.\d{2})?)(?:\h*-\h*\1(?2))?$

По частям

  • ^ Началострока
  • ( Захват группа 1
    • [$£]? По выбору соответствует $ или £
  • ) Закрыть группу
  • ( Захват Группа 2
    • (?:\d{1,3}(?:,\d{3})* Совпадение 1-3 цифр и повторение 0+ раз совпадения , и 3 цифры
    • | Или
    • \d+ Совпадение 1+ цифр
    • \b Граница слова
    • (?:\.\d{2})? При желании сопоставить точку и 2 цифры
  • ) Закрыть группу
  • (?: Группа без захвата
    • \h*-\h*\1 Совпадение - между 0+ горизонтальными пробелами, после которых следует символобратная ссылка на то, что захвачено вгруппа 1 (необязательно $ или £)
    • (?2) Повторите шаблон в группе 2 , чтобы соответствовать цифрам
  • )? Закрыть группу и сделать ее необязательной
  • $ Конец строки

Regex demo

0 голосов
/ 21 сентября 2019

Если вы получите дефис -, это означает, что у вас есть диапазон.Для простоты я бы взорвал () на дефисе и проверил каждую часть в цикле с помощью $ numberFormatter = new NumberFormatter ('en_US', NumberFormatter :: CURRENCY);var_dump ($ numberFormatter-> formatCurrency (1234.56789, "USD"));

Если средство форматирования может вернуть строку, это означает, что ввод действителен.

Это сработает, даже если вместо диапазона указан размер зарплаты.

0 голосов
/ 20 сентября 2019

Это должно быть очень строгое с единственным незначительным исключением (о котором я знаю):

^([$£]?((((\d{1,3},)*\d{3})|\d+)(\.\d{2})?)(\s*-\s*(?=[$£\d]))?){1,2}$

Объяснение

Вот как работают различные части регулярного выражения:

  • ^(...){1,2}$ Используется квантификатор, чтобы ограничить результат максимум двумя терминами.
  • [[$£]? Каждый термин может начинаться с необязательного символа.
  • ЧтоДалее следует число в одном из двух форматов:
    • ((\d{1,3},)*\d{3}) Форматированное число с 3 цифрами, разделенными запятой
    • |\d+ Или строка цифр.
  • (\.\d{2})?) После запятой может следовать десятичная часть.
  • (\s*-\s*(?=[$£\d]))? Разделитель диапазона может заканчиваться термином, только если следует символ или цифра валюты.

Демонстрация

Демонстрация включает в себя все предоставленные вами тесты, а также некоторые дополнительные случаи и отрицательные случаи, которые должны работать.

Проблемы

Единственное единственноеИзвестная проблема заключается в том, что символы валюты могут быть разными.

0 голосов
/ 20 сентября 2019

Это довольно строгое правило, так что все ваши записи из второй группы проходят, и ни одна из первой группы.

^[$£]?\d,?000(\.00)?([ -]+[$£]?\d,?000(\.00)?)?$

Вы можете сделать что-то гораздо более доброжелательное.Например, замените [$£] на \D, чтобы разрешить произвольную валюту и т. Д.

Проверьте это

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...