Регулярные выражения Tcl
set d(aa1) 1
set d(aa2) 1
set d(aa3) 1
set d(aa4) 1
set d(aa5) 1
set d(aa6) 1
set d(aa7) 1
set d(aa8) 1
set d(aa9) 1
set d(aa10) 1
set d(aa11) 1
set regexp "a*\[1-9\]"
set res [array names d -glob $regexp]
puts "res = $res"
В этом случае результат:
res = aa11 aa6 aa2 aa7 aa3 aa8 aa4 aa9 aa5 aa1
Но когда я изменяю регулярное выражение из a*\[1-9\]
в a*\[1-10\]
В результате получается:
res = aa11 aa10 aa1
2 ответа
У вас есть ошибка в вашем классе персонажей.
[1-10]
не означает цифру от 1 до 10- Это значит
1-1
, который является персонажем в диапазоне от1
в1
(т.е. просто1
) или0
, Это объясняет ваш вывод. - чтобы выразить цифру от 1 до 10, используйте это:
(?:10?|[2-9])
(как один из нескольких способов сделать это. - поэтому ваше регулярное выражение становится
a*(?:10?|[2-9])
- обратите внимание, что если ваш движок не позволяет группу без захвата, вам нужно удалить
?:
, за:a*(?:10?|[2-9])
Вы должны быть уверены, что вы пытаетесь соответствовать, потому что glob
соответствие стиля и regexp
соответствие стилей во многих отношениях различно.
Из документов, Glob имеет следующее:
*
соответствует любой последовательности символов в строке, включая нулевую строку.?
соответствует любому отдельному символу в строке.[chars]
соответствует любому символу в наборе, заданном символами. Если последовательность символов xy появляется в символах, то любой символ между x и y включительно будет совпадать. При использовании с-nocase
конечные точки диапазона сначала преобразуются в нижний регистр. В то время как{[A-z]}
Матчи_
при сопоставлении с учетом регистра (так как_
падает междуZ
а такжеa
), с-nocase
это считается как{[A-Za-z]}
(и, вероятно, что имелось в виду в первую очередь).\x
соответствует одному символуx
, Это позволяет избежать специальной интерпретации символов.*?[]\
в шаблоне.
Так как вы используете соответствие стиля глобуса, ваше текущее выражение (a*\[1-9\]
) соответствует a
сопровождаемый любыми символами и любым от 1 до 9 (означая, что это также будет соответствовать что-то вроде abcjdne1
).
Если вы хотите соответствовать хотя бы одному a
затем цифры от 1 до 10, вам нужно что-то вроде этого, используя -regexp
Режим:
set regexp {a+(?:[1-9]|10)}
set res [array names d -regexp $regexp]
Теперь, это регулярное выражение, я считаю, более естественным для начинающего ((?:[1-9]|10)
это означает от 1 до 9 или 10, но вы можете использовать форму, предложенную zx81 с (?:10?|[2-9])
означает 1, с необязательным 0 для 10 или от 2 до 9).
+
Значит это a
должен появиться хотя бы один раз, чтобы имя массива совпадало.
Если вам нужно сопоставить полные имена, вам нужно использовать якоря:
^a+(?:[1-9]|10)$
Примечание. Вы не можете использовать глобальное сопоставление, если хотите сопоставить хотя бы одно a
следуют цифры и чередование (труба используется |
) и квантификаторы (?
или же +
или же *
) их поведение в регулярном выражении не поддерживается сопоставлением глобусов.
И последнее: используйте фигурные скобки, чтобы избежать выхода из шаблона (если у вас нет переменной или функция в шаблоне и вы не можете сделать иначе).