jktstance
jktstance

Reputation: 165

Passing a variable to regexp when the variable may have brackets (TCL)

In my job, I deal a lot with entities whose names may contain square brackets. We mostly use tcl, so square brackets can sometimes cause havoc. I'm trying to do the following:

set pat {pair_shap_val[9]}
set aff {pair_shap_val[9]_affin_input}
echo [regexp "${pat}_affin.*" $aff]

However, this returns a 0 when I would expect a 1. I'm certain that when ${pat} is passed to the regexp engine, the brackets are being expanded and read as "[9]" instead of "[9]".

How do I phrase the regexp so a pattern contains a variable when the variable itself may have special regexp characters?

EDIT: An easy way would be to just escape the brackets when setting $pat. However, the value for $pat is passed to me by a function so I cannot easily do that.

Upvotes: 1

Views: 982

Answers (1)

glenn jackman
glenn jackman

Reputation: 246764

Just ruthlessly escape all non-word chars:

set pat {pair_shap_val[9]}
set aff {pair_shap_val[9]_affin_input}
puts [regexp "${pat}_affin.*" $aff]         ;# ==> 0

set escaped_pat [regsub -all {\W} $pat {\\&}]
puts $escaped_pat                           ;# ==> pair_shap_val\[9\]
puts [regexp "${escaped_pat}_affin.*" $aff] ;# ==> 1

A second thought: this doesn't really seem to require regular expression matching. It appears you just need to check that the pat string is contained in the aff string:

% expr {[string first $pat $aff] != -1}
1

Upvotes: 1

Related Questions