Operating System - HP-UX
1753318 Members
6291 Online
108792 Solutions
New Discussion юеВ

Negate matching group in perl

 
SOLVED
Go to solution
wojtek75
Frequent Advisor

Negate matching group in perl

Hi,

there is a text like that:
start in
start out
start off
start in
start away
start with
...

I like to match lines:
start (in|out)
but don't like to match lines with all other prepositions:
start (off|away|back|with|...)

How can I implement it in perl? The '^' doesn't seem to negate the () grouping and
the following doesn't work:
m/start\s^(in|out)/

I would appreciate your help with it.
12 REPLIES 12
James R. Ferguson
Acclaimed Contributor
Solution

Re: Negate matching group in perl

Hi:

To match 'start (in|out)' you could simply do:

# perl -ne 'm{start\s+(?:in|out)} and print' file

...the (?:) gives grouping-only without capture.

You could also do:

# perl -ne 'm{start\s+(?=in|out)} and print' file

...where the (?=) denotes a positive look-ahead.

And then:

# perl -ne 'm{start\s+(?!in|out)} and print' file

...which is a negative look-ahead which yields what you seek.

Regards!

...JRF...
wojtek75
Frequent Advisor

Re: Negate matching group in perl

Thanks. Is such feature available in egrep command?
H.Merijn Brand (procura
Honored Contributor

Re: Negate matching group in perl

Only if egrep is built with PCRE support

(mine is)

in which case grep knows the option -P and expressions are interpreted perl-style

Enjoy, Have FUN! H.Merijn
Enjoy, Have FUN! H.Merijn
wojtek75
Frequent Advisor

Re: Negate matching group in perl

Thanks,

and yet another perl challange. If my file includes "start " phrase anywhere inside I want to return false. The only acceptable exception is exact "start with" phrase. Bear in mind that ie. "start without" should return false either as "without" matches here.

Thanks in advance for sharing your expertise.
James R. Ferguson
Acclaimed Contributor

Re: Negate matching group in perl

Hi (again):

In keeping with yesterday's thread:

# perl -nl -0377 -e 'print m{start\s+with\b}?1:0' file

Regards!

...JRF...
wojtek75
Frequent Advisor

Re: Negate matching group in perl

Thanks,

I think I was not too specific. This is what I need in meta. is a template for any word.

if scirpts includes "start " phrase then {
if anyword is "with" then {
return 1
} else {
return 0
}
} else {
return 1
}

The goal is to find files with "start " which I find risky. The only acceptable exception is "start with" that I find safe.
Your solution returns false even when no "start " clause is there.
James R. Ferguson
Acclaimed Contributor

Re: Negate matching group in perl

Hi (again):

Per your last comments, you might do:

# perl -ne '$n++ if m{start\s+(?!with\b)};exit 1 if (m{start\s+with\b} and $n)' file;echo $?

Regards!

...JRF...
wojtek75
Frequent Advisor

Re: Negate matching group in perl

Thanks,

now I isolated my problem to the following:

if [[ $(perl -nl -0377 -e 'print m{start[\s\n]+(?!with\b)}i;' a.txt) -gt 0 ]]; then
print "Start non-with"
else
print "Start with"
fi

The input files are as follows (_ is for space):
1. =======
start with
2. =======
start
with
3. =======
start_
with
4. =======
start

with
======

1st and 2nd input returns "Start with" message. Why 3rd and 4th don't?
James R. Ferguson
Acclaimed Contributor

Re: Negate matching group in perl

Hi:

Let's simplify things. You're looking for the sequence "start with" so:

if [[ -z "$(perl -nl -0377 -e 'print m{start\s+with\b}i' ${FILE})" ]]; then
print "Start non-with"
else
print "Start with"
fi

...

Nothing will be returned if no match is found, hence, we will compare (in the shell) for an empty string.

Regards!

...JRF...