Question

As I was asked to match the string "[0-9]" (please note i dont mean to match number 0 to 9) I used

set a {[0-9]}
regexp  {\[0-9\]} $a out

which works perfectly., But anyway In an interview i was asked to not use {} to enclose the pattern and to do it alternatively with "" or something else

regexp  "\[0-9\]" $a out

But strangely when i use "" i can only match only 0

Is there anyway it can be done without {} in regexp

Était-ce utile?

La solution

I'm not sure why you need to use regexp to do that. You could use string methods, such as string match which uses glob matching:

string match {*[0-9]*} $a

* will match anything, it's a wildcard in glob matching.

Or you could use string first with expr, which basically returns 1 if the returned index is above -1 (i.e. the [0-9] is in the string $a) or 0 otherwise (i.e. there is no [0-9] in the string $a):

expr {[string index {[0-9]} $a] > -1}

Anyway, if you really want a regex, you'll have some escaping to do:

regexp {\[0-9\]} $a out

Note that you won't need the $out since you are looking for an exact match of something that cannot change, so you might as well use regexp {\[0-9\]} $a

Or use a syntax which tells regexp to treat the string literally:

regexp {***=[0-9]} $a

or

regexp {(?q)[0-9]} $a

Where ***= and (?q) tells regexp to treat the following characters as literal ones.

You can learn more about the re syntax on this man page.


But strangely when I use "" I can only match only 0

That's because what you are passing to the regexp engine is [0-9]. This is because the \[ and \] are being substituted before passing the expression to regexp. So you are actually having the expression [0-9] being passed, which will match any single digit.

Autres conseils

In Tcl, {} is just a quoting mechanism. You never need it, but it can be really annoying to write code without it. Let's write without any quotes at all:

regexp \\\[0-9\\\] $a out

Notice that we've got triple backslashes in there, because we want one backslash for the RE engine (which prevents the [ being a character set) and one backslash for each character of of \[ (which stops the Tcl basic syntax engine from interpreting things). We could put double quotes around it; all they really do is stop the basic syntax engine from detecting the end of the word until it hits the matching close of the double quotes, but we're not using any whitespace at all in the RE so it doesn't matter. It's conventional to put double quotes around things that people think of as strings for highlighting purposes, but Tcl doesn't really work that way.

In fact, one of Tcl's main claims to fame is just how few special syntax forms it really has, and how it applies them consistently to everything. For example, we can write procedures entirely without the use of braces:

proc foo "a b" "
    for set\\ i\\ \\\$a \\\$i\\ <\\ \\\$b incr\\ i puts\\ \\\$i...
"

That's code that works just fine; it's functionally identical to:

proc foo {a b} {
    for {set i $a} {$i < $b} {incr i} {puts $i...}
}

But which is the clearer one to write? The easier one to write? I think the answer is self-evident! Know that you never need to use braces, but for goodness' sake use braces in reality!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top