1

I'm in the process of migrating a setup from apache to nginx. In this process I've come across this rewrite rule in an .htaccess file:

RewriteRule ^/?(?:(?!one|two|three|four).?)+/?$ http://somewhere.else.com [R=301,L]

I'm pretty good at regex usually, but this is way beyond me. For starters, I didn't know embedded parenthesis were even allowed. Can someone explain this regex to me? And if it's an apache only thing, how I can replicate it in nginx?

1
  • It's standard PCRE, if nginix is using PCRE it should Just Work.
    – DerfK
    Aug 5, 2011 at 20:13

2 Answers 2

4
  1. (?!one|two|three|four) means "NOT (one or two or three or four)".

  2. The ?: means non-catching group (so you cannot reference it using $N, e.g. $1).

  3. All together it pretty much means ANY text that has no "one" or "two" or "three" or "four" sequence in it.

For example:

This URL /categories/category-1/hello-kitten/ if applied to the above rule, will be redirected. But this one /categoneries/category-1/hello-kitten/ will not, as it has sequence one in it: /categ***one***ries/category-1/hello-kitten/

2

Here's some more specific and detailed info in case it helps:

' ^/?(?:(?!one|two|three|four).?)+/?$ http://somewhere.else.com [R=301,L]
' 
' Options: case insensitive
' 
' Assert position at the beginning of the string «^»
' Match the character “/” literally «/?»
'    Between zero and one times, as many times as possible, giving back as needed (greedy) «?»
' Match the regular expression below «(?:(?!one|two|three|four).?)+»
'    Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
'    Assert that it is impossible to match the regex below starting at this position (negative lookahead) «(?!one|two|three|four)»
'       Match either the regular expression below (attempting the next alternative only if this one fails) «one»
'          Match the characters “one” literally «one»
'       Or match regular expression number 2 below (attempting the next alternative only if this one fails) «two»
'          Match the characters “two” literally «two»
'       Or match regular expression number 3 below (attempting the next alternative only if this one fails) «three»
'          Match the characters “three” literally «three»
'       Or match regular expression number 4 below (the entire group fails if this one fails to match) «four»
'          Match the characters “four” literally «four»
'    Match any single character that is not a line break character «.?»
'       Between zero and one times, as many times as possible, giving back as needed (greedy) «?»
' Match the character “/” literally «/?»
'    Between zero and one times, as many times as possible, giving back as needed (greedy) «?»
' Assert position at the end of the string (or before the line break at the end of the string, if any) «$»
' Match the characters “ http://somewhere” literally « http://somewhere»
' Match any single character that is not a line break character «.»
' Match the characters “else” literally «else»
' Match any single character that is not a line break character «.»
' Match the characters “com ” literally «com »
' Match a single character present in the list “R=301,L” «[R=301,L]»

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .