Discussion:
How to have lsearch handle square brackets in the list?
(too old to reply)
Frank
2015-06-12 21:45:02 UTC
Permalink
Hi,

I just hit this corner case. Is there a way to do this or a better way to search for these type of strings in a list?

As you can see from the example below lsearch fails to find the match when square brackets are used in the list elements.

% set a {A[0]}
A[0]
% lsearch $a $a
-1
% set a {A\[0\]}
A\[0\]
% lsearch $a $a
0


Thanks in advance,
Frank
Eric
2015-06-12 22:46:47 UTC
Permalink
Post by Frank
Hi,
I just hit this corner case. Is there a way to do this or a better way
to search for these type of strings in a list?
As you can see from the example below lsearch fails to find the match
when square brackets are used in the list elements.
% set a {A[0]}
A[0]
% lsearch $a $a
-1
% set a {A\[0\]}
A\[0\]
% lsearch $a $a
0
Thanks in advance,
Frank
Not a corner case at all. The first argument to lsearch is a list,
the second is a pattern (i.e. a string). The default matching style
is -glob as in "string match", so the pattern is "A" followed by any
character from the set in the brackets, i.e. "0". No element of the list
(all 1 of them) looks like this, so the return is -1.

In the second case the brackets are escaped so they do not represent a
character class but just themselves, so the pattern string matches the
single element of the list ( lindex $a 0 => A[0] ) and the return is 0.

Eric
--
ms fnd in a lbry
mango
2015-06-12 23:10:15 UTC
Permalink
Post by Frank
Hi,
I just hit this corner case. Is there a way to do this or a better way to search for these type of strings in a list?
As you can see from the example below lsearch fails to find the match when square brackets are used in the list elements.
% set a {A[0]}
A[0]
% lsearch $a $a
-1
% set a {A\[0\]}
A\[0\]
% lsearch $a $a
0
Thanks in advance,
Frank
Try "lsearch -exact". The default behavior is "lsearch -glob".

Andrew
Frank
2015-06-15 16:03:17 UTC
Permalink
Hi Andrew,

Is there a way to handle backslashes?

49 % set a {abc\\/cde/A[0]}
abc\\/cde/A[0]
50 % lsearch $a $a
-1
51 % lsearch -exact $a $a
-1

They are getting resolved/simplified by TCL even with the '-exact' flag.
Rich
2015-06-15 16:29:54 UTC
Permalink
Post by Frank
Hi Andrew,
Is there a way to handle backslashes?
49 % set a {abc\\/cde/A[0]}
abc\\/cde/A[0]
50 % lsearch $a $a
-1
51 % lsearch -exact $a $a
-1
They are getting resolved/simplified by TCL even with the '-exact' flag.
You are likely running into quoting hell with the above (as well as
shimmering variable a between string and list).

Backslashes work fine, provided you don't get too deep into quoting
hell:

% set a [list a b \\ c d]
a b \\ c d
% lsearch -exact $a \\
2

% set a [list a b a\\c d e]
a b {a\c} d e
% lsearch -exact $a a\\c
2
% set b a\\c
a\c
% lsearch -exact $a $b
2
Eric
2015-06-15 19:24:03 UTC
Permalink
Post by Frank
Hi Andrew,
Is there a way to handle backslashes?
49 % set a {abc\\/cde/A[0]}
abc\\/cde/A[0]
50 % lsearch $a $a
-1
51 % lsearch -exact $a $a
-1
They are getting resolved/simplified by TCL even with the '-exact' flag.
% set a {abc\\/cde/A[0]}
abc\\/cde/A[0]

the string value is, as we should expect, exactly what we put in

% lindex $a 0
abc\/cde/A[0]

using $a as a list in a list command forces the string to be treated as
the representation of a list - in which backslashes have meaning, so one
is removed according to that meaning

% set b {abc\/cde/A[0]}
abc\/cde/A[0]
% lsearch -exact $a $b
0

which show a match with the real value of a list element.

But

% set c [list {abc\\/cde/A[0]}]
{abc\\/cde/A[0]}
% lindex $c 0
abc\\/cde/A[0]
% lsearch -exact $c $a
0

which shows the right way to create a list.

Your original question turned out to be about matching options, but this
one is about the difference between the members of a list and the string
which represents the whole list.

Eric
--
ms fnd in a lbry
Frank
2015-06-13 12:49:31 UTC
Permalink
Thank you guys for the explanation and how to fix it. It is working now with the '-exact'.
Loading...