Вы сопоставляете символы , а не последовательности символов . По сути, вы сопоставляете 0, 1 с 1 и 2 (т.е. 0, 1 и 2). Учтите [a-z0-9], что это соответствует всем строчным буквам и всем цифрам, но только как один символ.
Лассе В. Карлсен
fwiw Я создал инструмент javascript, который создает высокооптимизированное регулярное выражение из двух входов (мин / макс) github.com/jonschlinkert/to-regex-range
jonschlinkert
0 [1-9] | 1 [0-2] -> 0 | 1 | 2 -> [] в регулярном выражении обозначают класс символов. Если диапазоны не указаны, он неявно использует каждый символ.
Badri Gs
Вам нужно сопоставить его с чистым регулярным выражением? Если нет, вы можете: 1. просто использовать \d+шаблон, 2.) преобразовать совпадающие строки в числа в вашем коде. а затем, 3.) проверьте диапазон номеров, например if(num >= 0 && num <= 12){ /*do something*/ }. Это намного быстрее и гибче.
acegs
Ответы:
198
Вы, кажется, неправильно поняли, как определение классов символов работает в регулярном выражении.
Для того, чтобы соответствовать любой из строк 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, или 12, что - то вроде этого произведения:
Числовые диапазоны (есть много примеров сопоставления строк, интерпретируемых как числовые диапазоны)
Объяснение
Класс символов сам по себе пытается сопоставить один и ровно один символ из входной строки. [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].
То есть -в определении класса символов не определяется числовой диапазон в шаблоне. Механизмы регулярных выражений на самом деле не «понимают» числа в шаблоне, за исключением синтаксиса конечного повторения (например, a{3,5}совпадений между 3 и 5 a).
Вместо этого определение диапазона использует кодировку символов ASCII / Unicode для определения диапазонов. Символ 0кодируется в ASCII как десятичное число 48; 9равно 57. Таким образом, определение символа [0-9]включает в себя все символы, значения которых находятся между десятичными числами 48 и 57 в кодировке. Скорее здраво, дизайн эти символы 0, 1, ..., 9.
Что касается меня, я месяцами искал без префикса 0, если одна цифра. И я использовал это ([1-9] | (1 [0-2])), и это работает.
bunjeeb
3
Важное примечание: если вы обнаружите, что на этой странице требуется решение для вашего диапазона номеров, в котором только однозначные цифры, прежде чем переходить к десяткам, 0[1-9]|1[0-2]не будет работать. Изменение его на следующий логический шаг [1-9]|1[0-2]не работает либо по понятным причинам (он совпадает с 1только 10, 11и 12). Пришлось использовать, \b(?:[0-9]|1[0-1])\bчтобы предотвратить это. \b's гарантирует, что регулярное выражение соответствует границам слова (или в данном случае числа) ( ^& $не было); скобки заставляют или ( |) учитывать обратную сторону; и, наконец, ?:не создавать подматч с использованием скобок.
user66001
@polygenelubricants: "1,2,3,4,5,6,7,8,9,10,17,18".match(/^(([1-9]|1[0-7])\,?)+$/g )Не могли бы вы сказать мне, почему это регулярное выражение JS соответствует более 17?
edam
@edam - polygenelubricants мог, и поэтому я мог, но тогда мы будем отвечать на questi ... Подождите ... является ли это вопрос вы задаете в комментарий ? На этом сайте есть рулезы ;) Задайте вопрос, если у вас есть новый вопрос. Комментарии предназначены только для критики и просьб о разъяснениях, а также для ответа на них.
robinCTS
1
@edam О, понятно. Вы же повторно задать его как вопрос час позже. Замечательно! Однако, вероятно, было бы неплохо удалить здесь свой комментарий.
robinCTS
24
Класс символов в регулярных выражениях, обозначенный [...]синтаксисом, определяет правила для сопоставления одного символа во входных данных. Таким образом, все, что вы пишете в скобках, указывает, как сопоставить один символ .
[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)
Затем вам нужно будет написать для этого регулярное выражение, которое может выглядеть так:
+--a0followedby1-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 . Надеюсь, вы сможете найти там дополнительную информацию, которая вам поможет.
Точнее [0-1][0-2]тоже совпадает 00. Тем не менее, +1 за ссылку (которую я использовал в своем ответе).
polygenelubricants
2
[0-1][0-2]следует осторожно интерпретировать, так как он допускает такие строки, как 00, 01и 02, но не допускает 03до 09, допуская наконец 10, 11и 12. Правильное регулярное выражение для этого есть [1-9]|1[0-2]или даже 0*([1-9]|1[0-2])(последнее допускает любое количество ведущих нулей).
Луис Колорадо
1
В []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. В общем, вы можете преобразовать любой диапазон чисел в действительное регулярное выражение аналогичным образом. Однако может быть лучший вариант, чем регулярные выражения, или существующая функция или модуль, которые могут построить регулярное выражение за вас. Это зависит от вашего языка.
Как говорит polygenelubricants, ваша будет искать 0 | 1-1 | 2, а не то, что вы хотите, из-за того, что классы символов (вещи в []) соответствуют символам, а не строкам.
[a-z0-9]
, что это соответствует всем строчным буквам и всем цифрам, но только как один символ.\d+
шаблон, 2.) преобразовать совпадающие строки в числа в вашем коде. а затем, 3.) проверьте диапазон номеров, напримерif(num >= 0 && num <= 12){ /*do something*/ }
. Это намного быстрее и гибче.Ответы:
Вы, кажется, неправильно поняли, как определение классов символов работает в регулярном выражении.
Для того, чтобы соответствовать любой из строк
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]
.То есть
-
в определении класса символов не определяется числовой диапазон в шаблоне. Механизмы регулярных выражений на самом деле не «понимают» числа в шаблоне, за исключением синтаксиса конечного повторения (например,a{3,5}
совпадений между 3 и 5a
).Вместо этого определение диапазона использует кодировку символов ASCII / Unicode для определения диапазонов. Символ
0
кодируется в ASCII как десятичное число 48;9
равно 57. Таким образом, определение символа[0-9]
включает в себя все символы, значения которых находятся между десятичными числами 48 и 57 в кодировке. Скорее здраво, дизайн эти символы0
,1
, ...,9
.Смотрите также
Другой пример: от А до Я
Давайте посмотрим на определение другого общего класса символов.
[a-zA-Z]
В ASCII:
A
= 65,Z
= 90a
= 97,z
= 122Это значит, что:
[a-zA-Z]
и[A-Za-z]
эквивалентны[a-Z]
вероятно, будет недопустимый диапазон символовa
(97) «больше», чемZ
(90)[A-z]
является допустимым, но также включает следующие шесть символов:[
(91),\
(92),]
(93),^
(94),_
(95),`
(96)Связанные вопросы
источник
0[1-9]|1[0-2]
не будет работать. Изменение его на следующий логический шаг[1-9]|1[0-2]
не работает либо по понятным причинам (он совпадает с1
только10
,11
и12
). Пришлось использовать,\b(?:[0-9]|1[0-1])\b
чтобы предотвратить это.\b
's гарантирует, что регулярное выражение соответствует границам слова (или в данном случае числа) (^
&$
не было); скобки заставляют или (|
) учитывать обратную сторону; и, наконец,?:
не создавать подматч с использованием скобок."1,2,3,4,5,6,7,8,9,10,17,18".match(/^(([1-9]|1[0-7])\,?)+$/g )
Не могли бы вы сказать мне, почему это регулярное выражение JS соответствует более 17?Класс символов в регулярных выражениях, обозначенный
[...]
синтаксисом, определяет правила для сопоставления одного символа во входных данных. Таким образом, все, что вы пишете в скобках, указывает, как сопоставить один символ .[01-12]
Таким образом, ваш шаблон разбивается следующим образом:Итак, в основном все, что вам нужно, это 0, 1 или 2.
Чтобы выполнить нужное сопоставление, сопоставив две цифры в диапазоне от 01 до 12 в виде чисел, вам нужно подумать о том, как они будут выглядеть как текст.
У тебя есть:
Затем вам нужно будет написать для этого регулярное выражение, которое может выглядеть так:
+-- 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 . Надеюсь, вы сможете найти там дополнительную информацию, которая вам поможет.
источник
Это тоже работает:
^([1-9]|[0-1][0-2])$
[1-9]
соответствует однозначным числам от 1 до 9[0-1][0-2]
соответствует двузначным числам от 10 до 12Есть несколько примеров хороших здесь
источник
[0-1][0-2]
тоже совпадает00
. Тем не менее, +1 за ссылку (которую я использовал в своем ответе).[0-1][0-2]
следует осторожно интерпретировать, так как он допускает такие строки, как00
,01
и02
, но не допускает03
до09
, допуская наконец10
,11
и12
. Правильное регулярное выражение для этого есть[1-9]|1[0-2]
или даже0*([1-9]|1[0-2])
(последнее допускает любое количество ведущих нулей).В
[]
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
. В общем, вы можете преобразовать любой диапазон чисел в действительное регулярное выражение аналогичным образом. Однако может быть лучший вариант, чем регулярные выражения, или существующая функция или модуль, которые могут построить регулярное выражение за вас. Это зависит от вашего языка.источник
Как говорит polygenelubricants, ваша будет искать 0 | 1-1 | 2, а не то, что вы хотите, из-за того, что классы символов (вещи в []) соответствуют символам, а не строкам.
источник
0|1-1|2
- это обозначение вводит в заблуждение. Что-то вроде0|1|2
было бы точнее.Использовать это:
0?[1-9]|1[012]
Чтобы протестировать паттерн на 07/2018, используйте это:
/^(0?[1-9]|1[012])\/([2-9][0-9]{3})$/
(Диапазон дат от 01/2000 до 12/9999)
источник