как lsearch в списке всегда совпадает

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

blabla.aa
cc.oiwerwer
asfd.Dd.asoiwer

и я хочу проверить, есть ли он в списке (верхний регистр следует игнорировать).

bind pub "-|-" !tt tt
proc tt {nick host handle channel arg} {

    set name [lindex [split $arg] 0]
    set groups {aa BB Cc DD Ee Ff gg hh}

    if {[lsearch -inline $groups $name] != -1} {
        putnow "PRIVMSG $channel :match name $name"
    }
}

Неважно, что я пишу, это всегда говорит о совпадении...

С Уважением


person Mike Shiwa    schedule 13.05.2019    source источник
comment
Каково значение $arg?   -  person glenn jackman    schedule 14.05.2019


Ответы (4)


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

bind pub "-|-" !tt tt
proc tt {nick host handle channel arg} {
    set name [lindex [split $arg] 0]
    set groups {aa BB Cc DD Ee Ff gg hh}

    foreach group $groups {
        if {[string match -nocase *$group* $name]} {
            putnow "PRIVMSG $channel :$name matched $group"
            break
        }
    }
}

тест кода

person Jerry    schedule 13.05.2019

Вы указали параметр "-inline" для lsearch. Он возвращает совпадение или пустую строку. Таким образом, это всегда не равно -1. Попробуйте удалить параметр "-inline". Кроме того, возможно, вы захотите использовать параметр "-exact".

Ссылка: https://www.tcl.tk/man/tcl8.6/TclCmd/lsearch.htm

person Chpock    schedule 13.05.2019
comment
когда я использую -inline, то это совпадение только тогда, когда $name BB точно совпадает, с BB.oiwerwer не работает - person Mike Shiwa; 13.05.2019
comment
невозможно использовать простые lsearch для ваших шаблонов. Вы должны перебрать все компоненты в файле $name. Например: foreach part [split $name .] { if { [lsearch -exact $groups $part] != -1 } { putnow "PRIVMSG $channel :...."; break } } - person Chpock; 13.05.2019

Если вы можете сделать так, чтобы ваш список вещей был в одном регистре (например, в нижнем регистре), вы можете использовать [string tolower] и оператор in для выполнения поиска. Это проще, чем lsearch, поскольку дает чистый двоичный результат:

proc tt {nick host handle channel arg} {
    set name [lindex [split $arg] 0]
    set groups {aa bb cc dd ee ff gg hh}

    if {[string tolower $name] in $groups} {
        putnow "PRIVMSG $channel :match name $name"
    }
}
person Donal Fellows    schedule 14.05.2019

Ваш вопрос немного неясен, но, собрав воедино некоторые подсказки, вы можете захотеть:

set channels {
    blabla.aa
    cc.oiwerwer
    asfd.Dd.asoiwer
}
set groups {aa BB Cc DD Ee Ff gg hh}

foreach group $groups {
    set idx [lsearch -nocase $channels "*$group*"]
    if {$idx != -1} {
        puts "$group -> [lindex $channels $idx]"
    }
}

который выводит

aa -> blabla.aa
Cc -> cc.oiwerwer
DD -> asfd.Dd.asoiwer

Или, гораздо более лаконично:

lsearch -inline -all -nocase -regexp $channels [join $groups |]
blabla.aa cc.oiwerwer asfd.Dd.asoiwer
person glenn jackman    schedule 14.05.2019