Как сопоставить числа между X и Y с регулярным выражением?

Я хотел бы совместить с RegExp число между X и Y. Возможно ли это?

([0-9] +) будет соответствовать любому числу, как я могу сделать, чтобы сопоставить число между, например, 110 и 2234?

Ответ 1

Согласно Создать регулярное выражение для соответствия произвольному числовому диапазону и после создания такого регулярного выражения для вашего примера в Regex_For_Range:

\b0*(1[1-9][0-9]|[2-9][0-9]{2}|1[0-9]{3}|2[01][0-9]{2}|22[0-2][0-9]|223[0-4])\b

сделал бы трюк.

Процесс будет (все еще следующий генератор Regex):

Сначала перейдите в равные длины:

110 - 999
1000 - 2234

Во-вторых, перейдите в диапазоны, которые дают простые регулярные выражения:

110 - 199
200 - 999
1000 - 1999
2000 - 2199
2200 - 2229
2230 - 2234

Поверните каждый диапазон в регулярное выражение:

1[1-9][0-9]
[2-9][0-9]{2}
1[0-9]{3}
2[01][0-9]{2}
22[0-2][0-9]
223[0-4]

Свернуть смежные степени 10:     1 [1-9] [0-9]     [2-9] [0-9] {2}     1 [0-9] {3}     2 [01] [0-9] {2}     22 [0-2] [0-9]     223 [0-4]

Объединение выражений выше дает:

0*(1[1-9][0-9]|[2-9][0-9]{2}|1[0-9]{3}|2[01][0-9]{2}|22[0-2][0-9]|223[0-4])

Далее мы попробуем разложить общие префиксы с помощью дерева:
Разбирайте в дерево на основе префиксов регулярных выражений:

. 1 [1-9] [0-9]
+ [0-9]{3}
+ [2-9] [0-9]{2}
+ 2 [01] [0-9]{2}
+ 2 [0-2] [0-9]
+ 3 [0-4]

Поворот дерева синтаксического анализа в регулярное выражение дает:

0*(1([1-9][0-9]|[0-9]{3})|[2-9][0-9]{2}|2([01][0-9]{2}|2([0-2][0-9]|3[0-4])))

В качестве результата мы выбираем более короткий.

\b0*(1[1-9][0-9]|[2-9][0-9]{2}|1[0-9]{3}|2[01][0-9]{2}|22[0-2][0-9]|223[0-4])\b

Ответ 2

Это не то, над чем существуют регулярные выражения. Вероятно, вам будет легче убедиться, что у вас есть правильное количество цифр /^([0-9]{3,4})$/, а затем выполните дополнительные проверки против захвата.

Ответ 3

В то время как вы могли бы сделать это с каким-то абсурдным выглядящим регулярным выражением (как ответил VonC), регулярное выражение действительно не должно это делать. Почему бы не отложить проверку числа до перенаправленного на script?

Если числа 110-2234 перейти к сценарию1 и 1-109 перейти к скрипту2, было бы гораздо проще направить все числа на router script и перенаправить его в правильное место (через перенаправления HTTP)..

В .htaccess:

RewriteRule ^view/([0-9]+)/?$ router.php?page=$1 [L]

.. то в router.php что-то вроде:

<?PHP
if(
   int($_GET['page']) > 110 &&
   int($_GET['page']) < 2234
){
    header("Status: 301 Moved Permanently\nLocation: /script1");
}else{
    header("Status: 404 Not Found");
}
?>

Ответ 4

Возможно, все не очень красиво.

\b(?:[1][1][0-9]|1\d{3}|223[0-4]|2[0-1]\d\d|2[0-2][0-3][0-4])\b

Я отправил по электронной почте Филлипу Хейзелю, автору PCRE, в 2006 году, что он думал о математике в регулярном выражении:

Возможно, это выходит за рамки проекта, на ваш взгляд: способность обрабатывать номера как числа, а не текст, это определенно будет полезной функцией. Позволяя вам выполнять некоторые основные математические проверки по совпадающим цифрам, например: это вторая совпадающая цифра выше или ниже, это третья цифра, кратная с 1-го, и многие более сложные случаи, о которых я не буду рассказывать, просто чтобы получить мою точку зрения, Считаете ли вы, что это превосходит сферу textmatching?

на который я получил следующий ответ:

Да, я думаю, что да, а также, это не то, что доступно в Perl обычные выражения. Я знаю, что PCRE имеет некоторые расширения от Perl, но ничего такого не значительного (вы возможно, взломать что-то, используя выноски, но это будет небольшая реклама hoc, и, без сомнения, чрезвычайно беспорядочно!).

Филипп

и я больше не мог согласиться на `09. Просто сопоставьте все номера и выполните проверку количества на любом языке, с которым вы выполняете сопоставление.

Ответ 5

Вы можете поместить регулярные выражения для следующих диапазонов вместе:

1[1-9]\d  = 110-199
[2-9]\d\d = 200-999
1\d\d\d   = 1000-1999
2[0-1]\d\d= 2000-2199
22[0-2]\d = 2200-2229
223[0-4]  = 2230-2234

чтобы сформировать:

(1[1-9]\d|[2-9]\d\d|1\d\d\d|2[0-1]\d\d|22[0-2]\d|223[0-4])

\ d означает [0-9], но в трех меньших символах