Почему регулярное выражение соответствует номерам от 1 до 10, которые обычно записываются следующим образом?
[1-9]|10
Вместо:
[1-10]
Или это:
[1-(10)]
Почему регулярное выражение соответствует номерам от 1 до 10, которые обычно записываются следующим образом?
[1-9]|10
Вместо:
[1-10]
Или это:
[1-(10)]
Когда-то хороший рисунок стоит 1000 слов...
Вот три предложения в вашем вопросе и способ, которым будет понимать их выражение:
Invalid regexp !!
Это регулярное выражение недействительно, потому что диапазон открыт (1-
) с цифрой, но не закрыт другой цифрой (заканчивается на (
).
Диапазон обычно связан с цифрами с обеих сторон или буквами с обеих сторон.
Это потому, что регулярные выражения работают с символами, а не с числами. [1-9]
эквивалентен (?:1|2|3|4|5|6|7|8|9)
, тогда как [1-10]
будет (?:1|0)
(потому что это диапазон 1-1 и цифра 0).
Проще говоря, диапазоны в символьных классах всегда относятся к смежным диапазонам символов, несмотря на то, как они выглядят. Даже если это цифры, это не означает, что существует какой-либо цифровой диапазон.
[1-9]|10
В этом:
[1-9]
принимает любой символ от 1 до 9;|
выполняет операцию "или";10
принимает буквально 10 букв.[1-10]
Это принимает:
0
.Независимо от того, какой шаблон находится внутри [...]
(класс символов), он соответствует только одному символу.
Как работает оператор диапазона (-
) внутри класса символов, он принимает один символ как левый операнд, а один символ - как правый операнд, затем разворачивает его до списка символов.
Итак, глядя на диапазоны в ваших примерах
1-9
(от 1 до 9) в [1-9]|10
(эквивалентно [123456789]|10
)1-1
(от 1 до 1) в [1-10]
(эквивалентно [10]
, который совпадает с [01]
)1-(
(от 1 до открывающей скобки) в [1-(10)]
1
до (
не имеет смысла.Здесь regex [1-9]
является эквивалентом
[123456789]
класс символов регулярных выражений, который соответствует одному символу. Когда вы помещаете тире в свое определение, как в b-e
, класс расширяется, чтобы включать концы (т.е. b
и e
) вместе со всеми символами с кодовыми точками между двумя концами (т.е. c
и d
). Оба конца могут быть одинаковыми, как в 1-1
, и в этом случае выражение эквивалентно 1
.
Вот почему [1-10]
функционально эквивалентен 0|1
.
Речь идет о совпадении символов. Когда вы говорите [1-9]
, это означает, что он соответствует любым индивидуальным символам от 1 до 9. Число 10 будет рассматриваться как два отдельных символа.
Это потому, что символы []
представляют набор символов, например. [0-5]
совпадений 0-5. Однако 10 имеет две цифры и, следовательно, [0-9]
не даст точное совпадение (будет соответствовать только первой цифре, "1" из "10".
Символ трубы |
можно рассматривать как оператор "или".
Это основное определение класса символов. [1-10]
означает "соответствие любому символу в диапазоне 1, хотя 1 или 0". Классы символов оцениваются по характеру (кроме escape-последовательностей и -
); они не понимают чисел.
[]
обозначает односимвольное соответствие
например [ab]
будет соответствовать либо a
, либо b
поэтому [1-9]
, который является эффективным сокращением для [123456789]
, будет соответствовать одному символу, который является одной из цифр от 1
до 9
Ваш пример [1-10]
будет расширять значение 1-1, чтобы означать все символы в диапазоне от 1
до 1
(т.е. 1
), поэтому фактическое регулярное выражение будет расширяться до [10] (т.е. либо символ 1 или символ 0)