set pattern {\Q[9]_i_1_n_0}
string first $pattern $pattern
# => 0
Matching с string first
сравнивает текстовое содержимое обеих строк без присвоения каких-либо особое значение символов. Результат 0 означает, что совпадение было найдено в позиции 0 (если нет совпадения, вы получаете -1). string first
не скажет вам, если вы нашли точное соответствие: для этого вам нужно убедиться, что результат равен 0, а длина строк одинакова.
Соответствие по «glob-style»/«string match» или регулярному выражению должно учитывать символы, которые являются особыми для соответствующих языков. Например, \
, *
, ?
, [
, ]
специальные в согласовании Glob стиле, и \
, .
, *
, +
, ?
, {
, }
, (
, )
, ^
, $
специальные в регулярных выражений. «Особый» в этом контексте означает, что, например, \
не означает «обратную косую черту», но (в обоих случаях) «побег», то есть символ, который отнимает «специальность» другого персонажа. Это означает, что, например, \\
означает обратную косую черту, а \*
означает звездочку.
Поскольку шаблон вы используете содержит как \
, [
и ]
, они должны быть экранированы до шаблон может быть использован для Glob-стиля или соответствия регулярных выражений. (На самом деле, по синтаксической причуде, ]
, которая закрывает сбежавший [
не нужно экранировать.)
Один из самых простых способов, чтобы избежать этих символов с помощью операции перевода строки выполняется командой string map
. Можно было бы подумать, что это будет делать трюк:
string map {\ \\ [ \[} $pattern ;# error! this code won't work!
, но это не будет работать, так как обратные косые все еще особенные в команде string map
.Мы должны точно удвоить количество слеша карты:
string map {\\ \\\\ [ \\[} $pattern
и теперь мы можем попытаться использовать сопоставление Глобо-стиль/регулярное выражение:
string match [string map {\\ \\\\ [ \\[} $pattern] $pattern
# => 1
regexp [string map {\\ \\\\ [ \\[} $pattern] $pattern
# => 1
Результат 1 означает булево истину: а матч найден. Обратите внимание, что результаты будут отличаться, если есть префикс и/или суффикс:
string match [string map {\\ \\\\ [ \\[} $pattern] abc${pattern}def
# => 0
regexp [string map {\\ \\\\ [ \\[} $pattern] abc${pattern}def
# => 1
Это происходит потому, что матч строки неявно закреплен на концах образца, в то время как регулярное выражение должно быть явным образом закреплены или это будет игнорировать предшествующий или удачный текст.
Соответствие в списке аналогично. lsearch -exact
работает как string first
, за исключением того, что он будет принимать ровно равные строки. lsearch -regexp
и lsearch -glob
работают как регулярное выражение и совпадение в стиле glob, соответственно.
set list [concat abc $pattern def]
# => abc \Q[9]_i_1_n_0 def
lsearch -exact $list [join $pattern]
# => 1
lsearch -regexp $list [string map {\\ \\\\ [ \\[} [join $pattern]]
# => 1
lsearch -glob $list [string map {\\ \\\\ [ \\[} [join $pattern]]
# => 1
Результат 1 здесь означает, что второй элемент в списке (индекс 1) соответствует шаблону.
(Использование concat
и join
является немного низкого уровня обмана, чтобы избежать скобки в строке представления получить в пути.)
Документация: concat, join, lsearch, Syntax of Tcl regular expressions, regexp, string
Вы пробовали двойную обратную косую черту '\\\'? –
http://stackoverflow.com/questions/19495405/tcl-backslash-issue-regsub –