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

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

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

Ответы [ 5 ]

45 голосов
/ 24 марта 2009

Согласно Создайте регулярное выражение для соответствия произвольному числовому диапазону , и после генерации такого регулярного выражения для вашего примера на 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
18 голосов
/ 24 марта 2009

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

4 голосов
/ 26 марта 2009

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

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

In .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");
}
?>
3 голосов
/ 15 сентября 2014

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

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], но тремя символами меньше

3 голосов
/ 24 марта 2009

Возможно, хотя и не красиво.

\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-му, и во многих более сложных случаях, которые я не буду развивать, просто для того, чтобы объяснить свою точку зрения , Считаете ли вы, что это выходит за рамки сопоставления текста?

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

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

Philip

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

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