Reputation: 87
I am unable to match regex with a pin name having patterns with /
and []
. How to match string with this expression in tcl regexp?
% set inst "channel/rptrw12\[5\]"
channel/rptrw12[5]
% set pin "channel/rptrw12\[5\]/rpinv\[11\]/vcc"
channel/rptrw12[5]/rpinv[11]/vcc
% regexp -nocase "^$inst" $pin
0
% regexp -nocase vcc $pin
1
% set pat "ctrl/crdtfifo"
ctrl/crdtfifo
% set pin2 "ctrl/crdtfifo/iwdatabuf"
ctrl/crdtfifo/iwdatabuf
% regexp -nocase $pat $pin2
1
Upvotes: 0
Views: 1207
Reputation: 137567
Your problem is that you are fighting with RE engine metacharacters, specifically […]
, which defines a character set. If you want to continue using your current approach, you'll need to add more backslashes.
If you are asking the question “does this string exist in that string?” you can also consider using one of these:
Use string first
and check if the result (where the substring is) is not negative:
if {[string first $inst $pin] >= 0} {
puts "Found it"
}
Use regexp ***=
, which means “interpret the rest of this as a literal string, no metacharacters”:
if {[regexp ***=$inst $pin]} {
puts "Found it"
}
If you only want to match for equality at the start of the string (you're asking “does this string start with that string?”) you probably should instead do one of these:
Use string first
and check if the resulting index is zero:
if {[string first $inst $pin] == 0} {
puts "Found '$inst' at the start of '$pin'"
}
Use string equal
with the right option (very much like strncmp()
in C, if you know that):
if {[string equal -length [string length $inst] $inst $pin]} {
puts "'$pin' starts with '$inst'"
}
Upvotes: 1
Reputation: 113866
If you remember your regular expressions, the []
syntax has special meaning in regexp. It defines a character group. For example:
[abc]
means match a
or b
or c
.
Therefore the pattern:
channel/rptrw12[5]
means match the string:
channel/rptrw125
If you want to match the literal character [
in regexp you need to escape it (same with all other characters that have meaning in regexp like .
or ?
or (
etc.). So your pattern should be:
channel/rptrw12\[5\]
But remember, the characters \
and [
has special meaning in tcl strings. So your code must do:
set inst "channel/rptrw12\\\[5\\\]"
The first \
escapes the \
character so that tcl will insert a single \
into the string. The third \
escapes the [
character so that tcl will not try to execute a command or function named 5
.
Alternatively you can use {}
instead of ""
:
set inst {channel/rptrw12\[5\]}
Upvotes: 1