Почему диапазон [01-12] не работает должным образом? - PullRequest
78 голосов
/ 30 июня 2010

Я пытаюсь использовать шаблон диапазона [01-12] в регулярном выражении, чтобы соответствовать двум цифрам мм, но это не работает, как ожидалось.

Ответы [ 6 ]

168 голосов
/ 30 июня 2010

Вы, похоже, неправильно поняли, как работает определение классов символов в регулярном выражении.

Для сопоставления с любой из строк 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11 или 12, что-то вроде этого работает:

0[1-9]|1[0-2]

Ссылки


Объяснение

Класс символов сам по себе пытается сопоставить один и ровно один символ из входной строки.[01-12] фактически определяет [012], класс символов, который соответствует одному символу из ввода против любого из 3 символов 0, 1 или 2.

Определение диапазона -идет от 1 до 1, что включает в себя только 1.С другой стороны, что-то вроде [1-9] включает 1, 2, 3, 4, 5, 6, 7, 8, 9.

Начинающие часто делают ошибки, определяя такие вещи, как [this|that].Это не "работает".Это определение символа определяет [this|a], то есть оно соответствует одному символу из ввода против любого из 6 символов в t, h, i, s, | или a.Более чем вероятно (this|that) - это то, что предназначено.

Ссылки


Как определяются диапазоны

Итак, теперь очевидно, что шаблон типа between [24-48] hours не "работает".Класс символов в этом случае эквивалентен [248].

То есть - в определении класса символов не определяет числовой диапазон в шаблоне.Движки Regex на самом деле не «понимают» числа в шаблоне, за исключением синтаксиса с конечным повторением (например, a{3,5} совпадение от 3 до 5 a).

Вместо определения диапазона используется кодировка ASCII / Unicodeсимволов для определения диапазонов.Символ 0 кодируется в ASCII как десятичное число 48;9 равно 57. Таким образом, определение символа [0-9] включает в себя все символы, значения которых в кодировке находятся между десятичными 48 и 57.Весьма разумно, что по замыслу эти символы 0, 1, ..., 9.

См. Также


Другой пример: от A до Z

Давайте рассмотрим определение другого общего символа [a-zA-Z]

В ASCII:

  • A = 65, Z = 90
  • a = 97, z = 122

Это означает, что:

  • [a-zA-Z] и [A-Za-z] эквивалентны
  • В большинстве разновидностей [a-Z] может быть недопустимым диапазоном символов
    • , поскольку a (97)«больше чем» чем Z (90)
  • [A-z] допустимо, но также включает в себя следующие шесть символов:
    • [ (91), \ (92), ] (93), ^ (94), _ (95), ` (96)

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

22 голосов
/ 30 июня 2010

Класс символов в регулярных выражениях, обозначаемый синтаксисом [...], определяет правила для соответствия отдельному символу во входных данных.Таким образом, все, что вы пишете в скобках, указывает, как сопоставить один символ .

Ваш шаблон, [01-12], таким образом, разбивается следующим образом:

  • 0 - соответствует одной цифре 0
  • или, 1-1, соответствует одной цифре в диапазоне от 1 до 1
  • или, 2, соответствует одной цифре 2

Таким образом, в основном все, что вы сопоставляете, это 0, 1 или 2.

Для того, чтобы выполнить сопоставление, которое вы хотите, сопоставляя две цифры, начиная с 01-12 как числа, вы должны подуматьо том, как они будут выглядеть как текст.

У вас есть:

  • 01-09 (т.е. первая цифра 0, вторая цифра 1-9)
  • 10-12 (т.е. первая цифра 1, вторая цифра 0-2)

Затем вам нужно написать регулярное выражение для этого, которое может выглядеть следующим образом:

  +-- a 0 followed by 1-9
  |
  |      +-- a 1 followed by 0-2
  |      |
<-+--> <-+-->
0[1-9]|1[0-2]
      ^
      |
      +-- vertical bar, this roughly means "OR" in this context

Обратите внимание, что попытка объединить их, чтобы получить более короткое выражение, не удастся, давая ложноположительные совпадения для неверного ввода.

Например, шаблон [0-1][0-9] будет в основном соответствовать числам 00-19, что немного больше, чем вы хотите.

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

8 голосов
/ 30 июня 2010

Это также работает:

^([1-9]|[0-1][0-2])$

[1-9] соответствует одной цифре от 1 до 9

[0-1][0-2] соответствует двойной цифре от 10 до 12

Есть несколько хороших примеров здесь

1 голос
/ 30 июня 2010

[] с в регулярном выражении обозначает класс символов . Если диапазоны не указаны, то неявно или s каждый символ в нем вместе. Таким образом, [abcde] - это то же самое, что и (a|b|c|d|e), за исключением того, что оно ничего не захватывает; он будет соответствовать любому из a, b, c, d или e. Весь диапазон указывает набор символов ; [ac-eg] говорит: "соответствует любому из: a; любому символу от c до e; или g". Таким образом, ваше совпадение говорит «соответствует любому из: 0; любому символу от 1 до 1 (, т.е. , просто 1); или 2.

Ваша цель - указать диапазон номеров: любое число от 01 до 12, написанное двумя цифрами. В этом конкретном случае вы можете сопоставить его с 0[1-9]|1[0-2]: либо 0, за которым следует любая цифра от 1 до 9, либо 1, за которым следует любая цифра от 0 до 2. В общем, вы можете преобразовать любой диапазон чисел в действительное регулярное выражение аналогичным образом. Однако может быть лучше, чем регулярные выражения, или существующая функция или модуль, который может создать регулярное выражение для вас. Это зависит от вашего языка.

0 голосов
/ 23 января 2018

Используйте это:

0?[1-9]|1[012]
  • 07: действительный
  • 7: действительный
  • 0: не совпадает
  • 00: не совпадает
  • 13: не совпадает
  • 21: не совпадает

Чтобы проверить шаблон на 07/2018, используйте это:

/^(0?[1-9]|1[012])\/([2-9][0-9]{3})$/

(Диапазон дат от 01/2000 до 12/9999)

0 голосов
/ 30 июня 2010

Как говорит Polygenelubricants, ваш будет искать 0 | 1-1 | 2, а не то, что вы хотите, из-за того, что классы символов (вещи в []) соответствуют символам, а не строкам.

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