views:

99

answers:

3

What is the regex for this?

Match if string

  • NOT ( ends in .php OR ends in .html OR contains / )

Thank you!

Edit: I need the NOT part because the expression is to be used on an Apache mod rewrite, since I can't change the logic of mod _rewrite to avoid the NOT.

Edit: My initial effort was ([^/]+)(.html)$(^.php)$ -- which is monstrusly wrong

+3  A: 

It's a whole lot easier to do positive matches in regex than negative matches. Try searching for ends in .php OR ends in .html OR contains / and reverse the logic in your program.

With strict regular expressions, there isn't a general way to negate a given expression. With PCRE's you have the advantage of negative look-aheads, which significantly simplify the process of constructing a negated search, at the expense of performance.

^([^/]*\.(?!html$|php$)[^./]*)|[^/.]$
Eclipse
I can't because I need it for an Apache rewrite rule. :(
john
John, that information should be in the question!
Peter Boughton
@Peter Boughton : added, thanks
john
Looks like mod_rewrite does do negation - and I've added an appropriate answer for that - but I'd probably still go with the expression Eclipse has just added.
Peter Boughton
A: 

Use this regex -

(.*\.php$)|(.*\.html$)|(.*\/.*)
Gopi
Thank you for answering, but it misses the NOT part. It matches "foo.php" "fo/o" and "foo.html" . It should match all but that.
john
oops! may bad. let me update my regex
Gopi
+4  A: 

Apache mod_rewrite does support negation, according to this document.

In mod_rewrite, the NOT character ('!') is also available as a possible pattern prefix. This enables you to negate a pattern; to say, for instance: ``if the current URL does NOT match this pattern''. This can be used for exceptional cases, where it is easier to match the negative pattern, or as a last default rule.

So you should be able to do something like:

!^(.*?/.*|.*?\.(?:php|html)$)$

And that should match anything which does not contain / and does not end in .php or .html

Peter Boughton
Fantastic! Thank you very much. I was not aware of the ! feature. Hopefuly, I 'll ask in a better way next time.
john
No problem, we're all always learning. :)
Peter Boughton
Is it possible to add this as variable now ? I tried RewriteRule !^(.*?/.*|.*?\.(?:php|html)$)$ headers.php?a=$1 [NC,L] but it won't pass the variable
john
I guess since you're going a negative match, there's no direct way for the group to match, since you're matching things that might not match the group, so we need a non-negated match which excludes what you want. I can't remember if mod_rewrite supports negative lookbehind, but try this `RewriteRule ^([^/]*(?<!\.html$)(?<!\.php$))$ headers.php?a=$1 [NC,L]` and see if it works?
Peter Boughton