Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

TCL(Tool Command Language) Scripting

How to do a NOT in TCL?


Hi,
I have a program that uses tcl7.5 regexp to find the following
unix:.* (WARN|NOTICE)

I would like to alter this to something like.
unix:.* (WARN|NOTICE) && ![^core]

I have been told that TCL cannot handle logical NOTs, but I thought
I'd just
check with the experts in this group for confirmation.

I tested the second expression above using awk and of course it
worked.

I have also tried
unix:.* (WARN|NOTICE).*[^core]{0}

I'm not sure if I have the syntax correct above, but what I'm trying
to say is
look for unix: then any characters followed by a space, then EITHER
WARN or NOTICE, then
any characters, but only when there a '0' (zero) occurances of core.

Hmm, hope someone understands what I'm trying to do. ;-)

Cheers
Craig.

On May 31, 5:12 pm, cabkiz_fam@hotmail.com wrote:

Logical not is not part of any standard regular expression notation.
The regular languages are closed under complementation, which one can
see by taking a deterministic machine and swapping the accepting and
non-accepting states, but there isn't any straightforward
corresponding regular expression notation.

However, Tcl does support logical not at the expression level, so you
can do things like:

[regexp {unix:.* (WARN|NOTICE).*} $s] && ![regexp {unix:.* (WARN|
NOTICE).*core} $s]

where the first regular expression is more general and the second one
matches a subset of the strings matched by the first.

In the specific case you mention, though, a "regular expression" with
a negative forward assertion will work:

^unix:.* (WARN|NOTICE(?!core)$

The part (?!core) blocks matches ending in "core".

On May 31, 5:12 pm, cabkiz_fam@hotmail.com wrote:

Oh, I should say that Tcl 7.5 is very old. I think that it probably
doesn't support assertions since the new regular expression package
came in with Tcl 8.0. Why on earth are you using such an ancient Tcl?
cabkiz_fam@hotmail.com schrieb:
> Hi,
> I have a program that uses tcl7.5 regexp to find the following
> unix:.* (WARN|NOTICE)

If you wanted to match either WARN or NOTICE the expression
ought to be ((WARN)|(NOTICE)). Otherwise the only thing it
matches is WARNOTICE.

> I would like to alter this to something like.
> unix:.* (WARN|NOTICE) && ![^core]

I guess you do not mean "any character apart from c,e,o and r", right?
Because that's what [^core] means in a regular expression.

> I have been told that TCL cannot handle logical NOTs, but I thought
> I'd just
> check with the experts in this group for confirmation.

It can, just not in a single expression. You do
if {[regexp {.* ((WARN)|(NOTICE))} $String] && ![regexp core $String]} {
...

}

> I tested the second expression above using awk and of course it
> worked.

Not sure how you managed that. None of the expressions you posted
worked for the grep on /my/ machine.

> I have also tried
> unix:.* (WARN|NOTICE).*[^core]{0}

> I'm not sure if I have the syntax correct above, but what I'm trying
> to say is
> look for unix: then any characters followed by a space, then EITHER
> WARN or NOTICE, then
> any characters, but only when there a '0' (zero) occurances of core.

> Hmm, hope someone understands what I'm trying to do. ;-)

Lots of Greetings!
Volker

--
For email replies, please substitute the obvious.

En Fri, 01 Jun 2007 18:27:43 +0200, Volker Hetzer  
<firstname.lastn@ieee.org> escribi:

> (WARN|NOTICE)
> I have a program that uses tcl7.5 regexp to find the following
> unix:.* (WARN|NOTICE)
> If you wanted to match either WARN or NOTICE the expression
> ought to be ((WARN)|(NOTICE)). Otherwise the only thing it
> matches is WARNOTICE.

   Did you try it before answering?

(Documents) 1 % regexp {^(WARN|NOTICE)$} NOTICE
1
(Documents) 2 %

   Ramon Rib

I assume you are updating an old script that used to run on Tcl7.5,
but you will be using a more recent version of Tcl. In that case
you may be able to use the negative lookahead feature for regular
expressions. I have to admit I am usually surprised by the results
when I try to use this feature, but I think for your case this
should work:
   regexp {unix:.* (WARN|NOTICE)(?!.*core)} $str

Schelte.
--
set Reply-To [string map {nospam schelte} $header(From)]

cabkiz_fam@hotmail.com wrote:
> I would like to alter this to something like.
> unix:.* (WARN|NOTICE) && ![^core]

> I have been told that TCL cannot handle logical NOTs, but I thought
> I'd just check with the experts in this group for confirmation.

It doesn't handle logical negation, since that's a surprisingly non-
trivial concept with REs for fairly deep reasons. However, it does
provide some techniques that can help. Most important among these is
the negative lookahead assertion, which is *almost* negation. But with
some important restrictions, the most important of which are that they
cannot have backreferences in (not that that matters this time) and
that they are always non-greedy. They're also quite slow (though we
mitigate that by putting them at the end of the RE).

The RE you are looking for is probably something like this:
  unix:.*\m(WARN|NOTICE)\M(?!.*\mcore\M.*$).*

You'll want to make sure you put that in {braces}, of course. (The \m
and \M ensure that you don't get tripped up by words like "scores"...)

Donal (alas, no time to explain properly what this does today...)

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc