Как я извлекаю все соответствия с Tcl regex?

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

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

7
задан Alan Moore 30 July 2010 в 09:30
поделиться

2 ответа

В -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 шестнадцатеричных цифр
  • Если вы настаиваете на сопоставлении и , то последняя шестнадцатеричная строка ( H'4DC9 в вашем вводе) не может быть сопоставлено
    • Это объясняет, почему вы получаете 4D52 в исходном скрипте, потому что это последнее совпадение с &
    • . Возможно, избавьтесь от & или используйте (& | $) , то есть & или конец строки $ .

Ссылки

25
ответ дан 6 December 2019 в 06:35
поделиться

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

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

EDIT: здесь это снова, на этот раз с исправленным регулярным выражением (см. комментарии):

regexp -all -inline {H'[0-9A-F]+&} $string
2
ответ дан 6 December 2019 в 06:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: