Jean
Jean

Reputation: 22695

Regex equivalent

What is the regex equivalent of $string=~/[^x]/ if x is replaced by multi-character string say xyz ? i.e string doesn't contain contain xyz

I eventually want to match

$string = 'beginning string xyz remaining string which doesn't contain xyz';

using

$string =~/(<pattern>)xyz(<pattern>)xyz/

so that

$1 = 'beginning string '
$2 = ' remaining string which doesn't contain ' 

Upvotes: 1

Views: 108

Answers (3)

ikegami
ikegami

Reputation: 385897

(?:(?!STRING).)* is to STRING as [^CHAR]* is to CHAR.

(Actually, far more than just strings can be used in this fashion. For example, you can use STRING1|STRING2 just as well as for STRING.)

$string =~ /
    ( (?:(?!xyz).)* )
    xyz
    ( (?:(?!xyz).)* )
    xyz
/sx

If that matches, that will always match at position zero, so let's anchor it to prevent needless backtracking on failure.

$string =~ /
    ^
    ( (?:(?!xyz).)* )
    xyz
    ( (?:(?!xyz).)* )
    xyz
/sx

Upvotes: 3

Peter Alfvin
Peter Alfvin

Reputation: 29409

In your particular case, a non-greedy .* will work. That is:

(.*?)xyz(.*?)xyz

will give you what you're looking for, as shown in http://rubular.com/r/RtaMG6ZvWK

However, as pointed out in the comment from @ikegami below, this is a fragile approach. And it turns out there is a "string" counterpart to the character-based [^...] construct, as shown in @ikegami's answer https://stackoverflow.com/a/20367916/1008891

You can see this in rubular at http://rubular.com/r/zsO1F0nkXu

Upvotes: 3

codnodder
codnodder

Reputation: 1675

while (<>) {
    if (/(([^x]|x(?!yz))+)xyz(([^x]|x(?!yz))+)xyz/) {
      printf("'%s' '%s'\n", $1, $3);
    }
}

Upvotes: 0

Related Questions