I have to disjuncts
D= d1| d2|...|dn
and
F=f1|f2|...|fn
at the moment I check those two regexp with an if-statement looking like this:
if (($text_to_search =~ $D) && ($text_to_search !~ $F))
How can I negate F? Is it possible to use a negative lookaround for the whole disjunct Or every single disjunct of F?
I should look like this:
regexp = (d1)| (d2) | (d3) ... (dn) | NOT (f1) | NOT (f2) | ... | Not (fn)
The brackets are necessary for negating the pattern and not only the first single char, arn't they?
Edit:
for example D is: a|b|c|d
and F is: 1|2|3
now the the behaviour should be like this:
input: "abc" --> accepted
input: "a" --> accepted
input: "abc1" --> Not accepted
input: "2" --> NOT accepted
input: "a2bc1" --> Not accepted
(input: "xyz999" --> does not match - shouldn't be accepted)
The F-disjunct should be like "when seeing this in the input sequence do not match"
Yes, you can use a negative lookahead. Using your notation we can construct a shape of such a combined regex:
/(?!F)D/
There are nuances though. Lets consider a simple example.
my $patternD = '^(\d\d\d\d | \w\w)$';
my $patternF = 'AA | 12';
As you can see, patternD matches strings consisting of either 4 digits, or 2 word characters. PatternF matches either AA
or 12
. So the following fragment prints what we expect.
my $str = '1121';
print "patternD matches\n" if $str =~ /$patternD/x; # patternD matches
print "patternF matches\n" if $str =~ /$patternF/x; # patternF matches
Now, lets create a combined regex using a naive approach.
my $combined = "(?!($patternF))$patternD";
print "Combined regex matches\n" if $str =~ /$combined/x; # Combined regex matches?!
Oops, we have a false positive here! (rememeber, our combined regex should match if and only if regex D matches and F doesn't, but this is not the case). Why is this? The answer is simple. We made our combined regex so that if D matches at some position then F can only match from the same position. In this case D matches at the beginning of the $str
(the \d\d\d\d
alternative), where neither AA
nor 12
can match. The solution is simple, though. We should give F some flexibility by adding .*
before it. The final result is:
my $combined = "(?!.*($patternF))$patternD";
No matter where D matches, F still has a chance to match anywhere in the string.
This example shows that what you want to achieve is definitely doable, but you can't simply mix your two regexes together, you'd rather have to carefully examine the final result first.
HTH