[HE] 2015-10-08: `[lsearch]` determines which values in a list match a pattern. I want to determine which patterns in a list match a value. Here is my solution: Syntax: `searchPatList` ''mode value patList'' `mode` specifies the type of pattern, and is is one of: `-exact`: Exact string matching. `-glob`: `[glob]`-style matching as provided by `[string match]`. `-regexp`: `[regexp]` matching. `value` is a string to apply each pattern to. `patList` is a list of patterns. `searchPatList` returns the index of the the first pattern in `patList` that matches `value`, or `-1` if no pattern matches. ====== proc searchPatList {mode value patList} { set n 0 switch -exact -- $mode { -exact { foreach el $patList { if {$el eq $value} { return $n } incr n } return -1 } -glob { foreach el $patList { if {[string match $el $value]} { return $n } incr n } return -1 } -regexp { foreach el $patList { if {[regexp -- $el $value]} { return $n } incr n } return -1 } default { error "Unknown mode '$mode'!" } } return } ====== And the examples: ====== set patList [list \ {test 3.4.1} \ {dummy} \ {^test *[0-9.]*$} \ {test *} \ ] searchPatList -exact {test 3.4.1} $patList 0 searchPatList -exact {test 3.4.2} $patList -1 searchPatList -exact {dummy} $patList 1 searchPatList -glob {test 3.4.1} $patList 0 searchPatList -glob {test 3.4.2} $patList 3 searchPatList -glob {dummy} $patList 1 searchPatList -regexp {test 3.4.1} $patList 0 searchPatList -regexp {test 3.4.2} $patList 2 searchPatList -regexp {dummy} $patList 1 searchPatList -default {dummy} $patList Unknown mode '-default'! ====== ---- [PYK] 2015-10-08: `$patList` mixes patterns which are clearly intended to be used with some particular command, yet `searchPatList` only operates in one mode at a time, making the overall design a bit over-engineered. This type of situation just might be the right place to use `[if]` without bracing the expressions: ====== set matchers { {{test 3.4.1} eq [lindex @val@]} {0 && [lindex @val@]} {[string match {^test *[0-9.]*$} @val@]} {[string match {test *} @val@]} } foreach matcher $matchers { if [string map [list @val@ [list $val]] $matcher] { puts [list matched $matcher] break } } ====== The advantages of this approach are that patterns and their associated commands appear together, and arbitrary matching algorithms can be introduced as needed. The `[[lindex @val@]]` bit serves merely as an [identity function], which is one way to properly quote a value being inserted into an `[expr]` template. Note also the use of `[[list $val]]` which is the right way to escape a value being interpolated into a [Tcl Rules%|%Tcl script] [Template and Macro processing%|%template]. [HE] 2015-10-08: Hello [PYK] Thank you for the suggestion. Even if your approach doesn't match the quest written in the first line. Perhaps I doesn't explain enough what I want to archive. I want a procedure, which like [lsearch] provide the index of the matching list item or -1 in case of no match. But instead of a list of values which are checked against a single pattern, I have a single value and a list of pattern. Like [lsearch] the kind of pattern is defined by an option. With this information, you also understand, that patList is not a list of different kind of pattern. Even if I use in the test cases the same pattern for all three modes. The result of my procedure is a number which can be used with [if] as it can be done with [lsearch]. The results of the example shows exactly what I want to get as a result. For sure some could extend the procedure to add option which deliver additional different result sets as it could be done with [lsearch]. But this is nothing I need as I wrote the searchPatList. There is also a security issue in case the pattern list comes from outside the tcl script like a configuration file or the Tk GUI. I use a win64 system and add the pattern '{[exec more deda]}' to matchers. The external program 'more' is executed. If I add this pattern to patList and use it with searchPatList the external program 'more# is not executed. Think what happen with with other programs which could format your HD or do other harm. ---- [HE] 2015-10-08: Hello [pooryorick] you removed the option -- behind the switch instruction. There is nothing wrong with -- and there are a lot of persons which like to use it to prevent possible future errors. Even if it is not needed in a special case. Please accept that other person have a different opinion how to write code then yourself. Therefore, I changed it back and ask you not to change the code again. Let this wiki a place where diversity of writing tcl is possible. Thanks. <>String Processing