2013-10-03 4 views
-1

Как вы пишете регулярное выражение, которое соответствует числовому диапазону валюты от -214748.00 или до 214748.00?Выражение регулярных выражений в соответствии с числовым диапазоном валют

Я пробовал это, но не работал.

^[-]?[0-9]{1,214748 }(?:\\.[0-9]{2})?$ 
+3

Я должен спросить, есть ли у вас что-то числовое, почему вы используете регулярное выражение? – drobert

+0

Мое требование - ограничить числа, если оно превышает лимит, тогда мне нужно выбросить исключение –

+0

Это, безусловно, НЕ РАБОТАЕТ для регулярного выражения. Вы бы закололи гвоздь отверткой? Нет простого способа написать регулярное выражение для проверки того, что число находится в диапазоне, если пределы диапазона не равны 10 (то есть -100000 <= x <= 100000) –

ответ

5

Nonono. Вы используете неправильный инструмент для работы. Regex - это просто инструмент обработки текста. Это плохо при интерпретации смысла текста. Когда дело доходит до определения семантики текста, который нужно обработать, это то, где регулярное выражение не является хорошим.

Для этого задания необходимо использовать простой инструмент языка и операторы. Кроме того, если вы имеете дело с валютами, избегайте использования double или float. Они не имеют достаточной точности для точного представления всех чисел с плавающей запятой. Вместо этого используйте BigDecimal.


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

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

"-?(\\d{1,5}|1\\d{5}|2(?:0\\d{4}|1(?:[0-3]\\d{3}|4(?:[0-6]\\d{2}|7(?:[0-3]\\d|4[0-8])))))" 

-? означает необязательный - для отрицательного числа.

Демо-код:

String str = "-?(\\d{1,5}|1\\d{5}|2(?:0\\d{4}|1(?:[0-3]\\d{3}|4(?:[0-6]\\d{2}|7(?:[0-3]\\d|4[0-8])))))"; 

System.out.println("214748".matches(str)); // true 
System.out.println("214746".matches(str)); // true 
System.out.println("2148".matches(str)); // true 
System.out.println("-21448".matches(str)); // true 
System.out.println("-214747".matches(str)); // true 
System.out.println("214749".matches(str)); // false 

Регулярное выражение использует следующие факты.Для диапазона [-214748, 214748]:

  • Любые 5 или меньше цифр номера действительны - \\d{1,5}
  • Любой 6-значный номер, начинающийся с 1 действительны - 1\\d{5}
  • Для ряда, начиная с 2:
    • Далее 5 цифровые номера, начинающиеся с 0, действительны - 20\\d{4}
    • Если номер рядом с 2 - 1
      1. Любые дополнительные 4 цифры номера, начинающиеся с [0-3] действительны - 21[0-3]\\d{3}
      2. Для получения дополнительной 4-значный номер, начинающийся с 4:
        • номера, начинающиеся с [0-6] действительны - 214[0-6]\d{2}
        • Если цифра после 4 является 7, а затем
          1. Остальные номера, начиная с [0-3], действительны - 2147[0-3]\\d
          2. Если цифра после 7 является 4, то в диапазоне [0-8] после 4 действительна - 21474[0-8]
+1

@Downvoter Ухаживать за комментариями. –

+1

@NullUserException. Я не ответил, чтобы предоставить решение. Я только что добавил, почему regex не следует использовать, и дал понять, что следует использовать. Я ожидал бы, что OP по крайней мере выполнит эту работу с операторами. –

+1

Достаточно честный. Но я отказался от ответа до редактирования ниндзя – NullUserException

1

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

^-?((([0-9]{1,5}|1[0-9]{5}|2(0[0-9]{4}|1([0-3][0-9]{3}|4([0-6][0-9]{2}|7([0-3][0-9]|4[0-7])))))([.][0-9]{2})?)|214748([.]00)?)$ 

Это во многом зависит от следующих суб-регулярное выражение, которое соответствует диапазону от 0 до 214747:

([0-9]{1,5}|1[0-9]{5}|2(0[0-9]{4}|1([0-3][0-9]{3}|4([0-6][0-9]{2}|7([0-3][0-9]|4[0-7]))))) 

Почему от 0 до 214747, а не от 0 до 214748? Поскольку это делается так, проще избегать сопоставления значений с 214748.01 по 214748.99 (+/-). Ломая регулярное выражение, получим:

^ # match start of line 
-? # optional minus sign 
    (# match one of the following groups, this one: 
    (
    ([0-9]{1,5}|1[0-9]{5}|2(0[0-9]{4}|1([0-3][0-9]{3}|4([0-6][0-9]{2}|7([0-3][0-9]|4[0-7]))))) 
    # the sub-regex above matches the range from 0 to 214747 
    ([.][0-9]{2})? # this matches the optional two decimals 
    ) 

    | # or this one: 
    214748([.]00)? # 214748, with optional zeroes 
) 
$ # match end of line 

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

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

Смежные вопросы