Как извлечь все совпадения с помощью регулярного выражения Tcl? - PullRequest
7 голосов
/ 30 июля 2010

Привет всем, я хочу решение для этого регулярного выражения, моя проблема заключается в извлечении всех шестнадцатеричных чисел в форме H'xxxx, я использовал это регулярное выражение, но я не получил все шестнадцатеричные значения только я получаю одно число, как получить целоешестнадцатеричное число из этой строки

set hex "V5CCH,IA=H'22EF&H'2354&H'4BD4&H'4C4B&H'4D52&H'4DC9"
set res [regexp -all {H'([0-9A-Z]+)&} $hex match hexValues]
puts "$res H$hexValues"

получаю 5 H4D52

Ответы [ 2 ]

25 голосов
/ 30 июля 2010

Вкл. -all -inline

С документация :

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

-inline: команда возвращает в виде списка данные, которые в противном случае были бы помещены в переменные соответствия.При использовании -inline, переменные соответствия могут не указываться .Если используется с -all, список будет объединяться на каждой итерации, так что плоский список всегда возвращается .Для каждой итерации совпадения команда будет добавлять данные общего совпадения плюс один элемент для каждого подвыражения в регулярном выражении.

Таким образом, чтобы вернуть все совпадения - включая захваты по группам - как плоскостьВ списке в Tcl вы можете написать:

set matchTuples [regexp -all -inline $pattern $text]

Если в шаблоне есть группы 0…N-1, то каждое совпадение является N -тупле в списке.Таким образом, количество фактических совпадений - это длина этого списка, деленная на N.Затем вы можете использовать foreach с N переменными для итерации по каждому кортежу списка.

Если, например, N = 2, у вас есть:

set numMatches [expr {[llength $matchTuples] / 2}]

foreach {group0 group1} $matchTuples {
   ...
}

Ссылки


Пример кода

Вот решение этой конкретной проблемы, аннотированное с выводомкак комментарии ( см. также на ideone.com ):

set text "V5CCH,IA=H'22EF&H'2354&H'4BD4&H'4C4B&H'4D52&H'4DC9"
set pattern {H'([0-9A-F]{4})}

set matchTuples [regexp -all -inline $pattern $text]

puts $matchTuples
# H'22EF 22EF H'2354 2354 H'4BD4 4BD4 H'4C4B 4C4B H'4D52 4D52 H'4DC9 4DC9
# \_________/ \_________/ \_________/ \_________/ \_________/ \_________/
#  1st match   2nd match   3rd match   4th match   5th match   6th match

puts [llength $matchTuples]
# 12

set numMatches [expr {[llength $matchTuples] / 2}]
puts $numMatches
# 6

foreach {whole hex} $matchTuples {
   puts $hex
}
# 22EF
# 2354
# 4BD4
# 4C4B
# 4D52
# 4DC9

На шаблоне

Обратите внимание, что я немного изменил шаблон:

  • Вместо [0-9A-Z]+, например, [0-9A-F]{4} более конкретно соответствует точному совпадению 4 шестнадцатеричных цифр
  • Если вы настаиваете на совпадении с &, то последняя шестнадцатеричная строка (* 1065)* в вашем вводе) не может быть сопоставлено
    • Это объясняет, почему вы получаете 4D52 в исходном скрипте, потому что это последнее совпадение с &
    • Может быть, избавиться от &, или используйте (&|$) вместо, то есть & или конец строки $.

Ссылки

  • ** г тысяча восемьдесят-четыряegular-expressions.info/Finite Repetition , Якоря
2 голосов
/ 30 июля 2010

Я не Tclish, но я думаю, что вам нужно использовать оба параметра -inline и -all:

regexp -all -inline {H'([0-9A-Z]+)&} $string

РЕДАКТИРОВАТЬ: Вот и снова, на этот раз с исправленным регулярным выражением (смотрите комментарии):

regexp -all -inline {H'[0-9A-F]+&} $string
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...