Проблема с обратной ссылкой в ​​TCL

У меня есть следующий код:

set a "10.20.30.40"
regsub -all {.([0-9]+).([0-9]+).} $a {\2 \1} b

Я пытаюсь найти 2-й и 3-й октет IP-адреса.

Ожидаемый результат:

20 30

Фактический результат:

20 04 0

В чем здесь моя ошибка?


person Bharathi    schedule 19.05.2015    source источник
comment
Вам нужно бежать. символ, подобный \. . Не убегая, . соответствует любому символу.   -  person Min Naing Oo    schedule 19.05.2015
comment
попробовал то же самое, но безуспешно regsub -all {\.([0-9]+)\.([0-9]+)\.} $a {\2 \1} b   -  person Bharathi    schedule 19.05.2015
comment
@Бхарати: Извини. Ваше намерение мне непонятно. Вам нужно сопоставить 20.30. в переменной a и заменить его другим?   -  person Dinesh    schedule 19.05.2015
comment
Понятно. Вам нужно заменить .20.30 на 30.20. Верно ?   -  person Dinesh    schedule 19.05.2015
comment
@Bharathi: Если вы просто хотите сохранить 2-й и 3-й октет, то зачем вообще regsub? regexp достаточно, верно? Зачем еще и обратная ссылка?   -  person Dinesh    schedule 19.05.2015
comment
Это одна из ситуаций, когда регулярное выражение не подходит. Вы должны split вместо того, чтобы пытаться сделать это... [split $a .] дает вам {10 20 30 40}, который вы можете легко использовать lrange, чтобы собрать второй и третий элементы вместе...   -  person Jerry    schedule 19.05.2015


Ответы (2)


Вам нужно установить переменные для совпадений и захваченных групп, после чего вы сможете получить к ним доступ. Вот пример:

set a "10.20.30.40"
set rest [regexp {[0-9]+\.([0-9]+)\.([0-9]+)\.[0-9]+} $a match submatch1 submatch2]
puts $submatch1
puts $submatch2

Вывод демо

20
30

ИЗМЕНИТЬ:

Таким образом вы можете использовать regsub и backerferences (сейчас я заменяю 3-й и 2-й октеты просто для демонстрации). Обратите внимание, что буквальная точка должна быть экранирована:

set a "10.20.30.40"
regsub -all {\.([0-9]+)\.([0-9]+)\.} $a {.\2.\1.} b
puts $b

Вывод демо:

10.30.20.40

Чтобы получить строку «20 30», вам нужно использовать

regsub -all {^[0-9]+\.([0-9]+)\.([0-9]+)\.[0-9]+$} $a {\1 \2} b
person Wiktor Stribiżew    schedule 19.05.2015
comment
Спасибо за ваши усилия, но я хочу найти эти октеты, используя regsub и обратную ссылку. ... как упоминалось в моем вопросе, доступна команда regesub. Но это не работает - person Bharathi; 19.05.2015
comment
Спасибо :) .... он работает нормально .. Не могли бы вы сообщить мне какие-либо документы, чтобы понять обратную ссылку - person Bharathi; 19.05.2015
comment
Конечно, лучшая ИМО — это Regular-expressions.info. - person Wiktor Stribiżew; 19.05.2015
comment
у меня есть еще один вопрос, не могли бы вы мне помочь. установить 1 abc 2 abc 3 abc 4 abc 5 abc 6 abc 7 abcd . я хочу заменить первые 3 abc как bhu, используя regsub и обратную ссылку ... пожалуйста, помогите мне в этом .. - person Bharathi; 21.05.2015
comment
Вот вы: set a "1 abc 2 abc 3 abc 4 abc 5 abc 6 abc 7 abcd" \\NEWLINE regsub {([0-9]+\s+)abc( +[0-9]+ +)abc( +[0-9]+ +)abc(.*)} $a {\1bhu\2bhu\3bhu\4} b \\NEWLINE puts $b. Вместо \\NEWLINE используйте настоящую новую строку. - person Wiktor Stribiżew; 21.05.2015
comment
Кроме того, рассмотрите возможность голосования за ответ, если он оказался для вас полезным. - person Wiktor Stribiżew; 21.05.2015
comment
Привет, спасибо, здесь, можем ли мы использовать связанные квантификаторы или что-то еще для следующего сценария, потому что рассмотрим переменную a, имеющую 1 abc 2 abc ...... 100 abc, в которой я хочу сопоставить первые 50 совпадений abc .... затем наш regsub будет очень длинным ..... нам нужно избежать этого .... есть идеи ??? - person Bharathi; 22.05.2015

Я бы вообще держался подальше от регулярных выражений:

set b [join [lrange [split $a .] 1 2]]

Разделите значение на точки, возьмите 2-й и 3-й элементы и соедините их пробелом.

person glenn jackman    schedule 19.05.2015