Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to have lsearch handle square brackets in the list?

1,624 views
Skip to first unread message

Frank

unread,
Jun 12, 2015, 5:45:04 PM6/12/15
to
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

unread,
Jun 12, 2015, 7:10:06 PM6/12/15
to
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

unread,
Jun 12, 2015, 7:10:18 PM6/12/15
to
Try "lsearch -exact". The default behavior is "lsearch -glob".

Andrew

Frank

unread,
Jun 13, 2015, 8:50:32 AM6/13/15
to
Thank you guys for the explanation and how to fix it. It is working now with the '-exact'.

Frank

unread,
Jun 15, 2015, 12:03:19 PM6/15/15
to
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

unread,
Jun 15, 2015, 12:31:14 PM6/15/15
to
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

unread,
Jun 15, 2015, 3:40:06 PM6/15/15
to
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.
0 new messages