2013-09-15 3 views
0

Есть ли способ использовать индекс списка в регулярном выражении?индекс списка tcl в regexp

Я пытался с этим, но он не работает:

if {[regexp {.*\[lindex $mylist 2\].*} $mystring]} { 
    puts "OK" 
} 

значение находится по индексу списка 2 списка с именем MyList не заменяется в регулярном выражении.

Спасибо.

+0

Я не думаю, что регулярное выражение может включать переменные - все внутри \\ является частью регулярного выражения. – dax

+0

Возможно, если вы установите выражение с помощью '-all' и' -inline', а затем установите индекс списка из этого шаблона переменной. – hwnd

ответ

1

Если вы просто хотите увидеть, есть ли какая-то короткая простая строка в другом, regexp - неправильный подход. Вместо этого используйте string first:

if {[string first [lindex $mylist 2] $mystring] >= 0} { 
    puts "OK" 
} 

Если список действительно имеет регулярное выражение в его третий элемент, то этого достаточно, чтобы сделать это, потому что Tcl всегда обнаруживает, если RE соответствует в любом месте (это шаблоны unanchored по умолчанию):

if {[regexp -- [lindex $mylist 2] $mystring]} { 
    puts "OK" 
} 

-- только в том случае, RE начинается с - характер, что может привести к путанице.Вы можете также использовать regexp работать немного как то string first рецепт:

if {[regexp ***=[lindex $mylist 2] $mystring]} { 

Но код с string first будет быстрее! Если вам нужно что-то гораздо более сложное, это, вероятно, хорошая идея: остановите и подумайте, правильно ли вы выполняете то, что вы делаете; когда вы делаете сложные замены в регулярных выражениях, вы обычно попадаете в беспорядок. (Или, по крайней мере, это то, что я знаю I нужно переосмыслить.) Задавая здесь - при предоставлении немного больше контекста - может помочь вам разобраться.

+0

А, я, как правило, забываю о переключателях, вызывающих проблемы. Хорошая точка зрения! «*** =» - это что-то новое для меня. Интересно, как 'regexp' интерпретирует это. – Jerry

+1

@Jerry: Он интерпретирует все после ведущего '*** =' как литерала (unanchored). Документировано в re_syntax, но по-прежнему неясно ... –

+0

Большое спасибо, я сначала объединил несколько строк, чтобы получить результат, который я хочу. – user2669068

0

Проблема заключается в том, что скобки внутри регулярного выражения предотвращают оценку команды списка. Существуют различные способы решения этой проблемы, одна из которых - отказаться от фигурных скобок и использовать кавычки, которые позволяют оценивать команды. В этом случае вам нужно бежать управляющие символы:

if {[regexp ".*\\[lindex $mylist 2].*" $mystring]} { 
    puts "OK" 
} 

В качестве альтернативы можно использовать команду SUBST, но это будет многословным:

if {[regexp [subst -nobaclslashes {.*\[lindex $mylist 2\].*}] $mystring]} { 
    puts "OK" 
} 

Команда Подст с выключателем я позволил подменяет все внутри это, за исключением обратных косых черт.

1

Я не уверен, почему вы используете regexp таким образом. Знаете, вам не нужно сопоставлять целую строку?

Вы должны быть в состоянии использовать:

if {[regexp [lindex $mylist 2] $mystring]} { 
    puts "OK" 
} 

Обратите внимание, что до тех пор, пока существует совпадение где-нибудь в строке, регулярное выражение будет соответствовать и возврата 1.

Однако, это может дать вы получаете неожиданные результаты с метасимволами regexp. Если [lindex $mylist 2] не содержит, вы должны быть хорошими.

Если элемент в списке не был строкой регулярного выражения, то никаких проблем не возникнет.


Если у вас есть метасимволы в элементе списка, вы можете использовать другой регулярному_выражению первым, чтобы избежать их:

if {[regexp [regsub -all {[\]\[+*.^${}()?\\]} [lindex $mylist 2] {\\\0}] $mystring]} { 
    puts "OK" 
} 

[regsub -all {[\]\[+*.^${}()?\\]} [lindex $mylist 2] {\\\0}] добавляет обратную косую черту к метасимволов в [\[\]{}()?+*.^$\\] (т.е. следующие символы []+{}()?+*.^$\)

+1

Если у вас нет того, что вы считаете RE в списке, _rethinking весь подход_ будет мудрым шагом! –

+0

@DonalFellows Я не настолько хорошо знаком со всеми строковыми функциями, но вы думаете о чем-то вроде 'string first [lindex $ mylist 2] $ string'? – Jerry

+1

См. Мой ответ ... ;-) –

Смежные вопросы