Регулярные выражения 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 следуют цифры и чередование (труба используется |) и квантификаторы (? или же + или же *) их поведение в регулярном выражении не поддерживается сопоставлением глобусов.

И последнее: используйте фигурные скобки, чтобы избежать выхода из шаблона (если у вас нет переменной или функция в шаблоне и вы не можете сделать иначе).

Другие вопросы по тегам