2

What can be a possible regex to match any of the following:

Eggs and Legs
Legs and Eggs

I can only think of the following regex:

(Eggs|Legs) and (Eggs|Legs)

But i want to avoid matching:

Eggs and Eggs
Legs and Legs

PS: Edited my solution to add parenthesis,

1
  • 1
    That regex doesn't even work, you probably meant (Eggs|Legs) and (Eggs|Legs). Commented Dec 3, 2014 at 11:16

3 Answers 3

5

Use a capturing group and negative lookahead:

/(Eggs|Legs) and (?!\1)(?:Eggs|Legs)/

I.e. the first and the last word can be Eggs or Legs, but capture the first word (using (...)), and then make sure and isn't followed by that word (using negative lookahead ((?!...)) for whatever the first word was (\1)).

See it in action here.

Sign up to request clarification or add additional context in comments.

1 Comment

@VineetDeoraj See the updated answer. Is that a good enough explanation? (The link to Regex 101 has details for each and every part of the regex.)
3

This will capture both words surrounding and and will print them both unless the first captured word is the same as the second one:

use strict;
use warnings;

open my $in, '<', 'in.txt';

while(<$in>){
    chomp;
    my ($match1, $match2) = /(\w+) and (\w+)/;
        print "$match1\t$match2\n" unless $match1 eq $match2;
}

Comments

2

The regex you can only think of is not correct: it misses some parentheses. It in fact matches any string containing Eggs, Legs and Eggs, or Legs.

The correct form would be

/(Eggs|Legs) and (Eggs|Legs)/

To make it work, just check that $1 ne $2.

4 Comments

Thanks. "ne" as mentioned in @Biffen answer?
@VineetDeoraj: ne as mentioned in perlop, but both should work.
I was taking about how to implement ne with this example, similar to biffen's answer or you have some other thought on that?
@VineetDeoraj: Yes, just do print if /(Eggs|Legs) and (Eggs|Legs)/ and $1 ne $2;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.