Seemingly identical Regex Apache RewriteRule... What is the difference?
Dear folks, Im trying to figure out what's the difference between these two
R开发者_如何学PythonewriteRule ^([a-z][a-z])/(.*?)(-.*)?$ /$2?ln=$1 [L]
RewriteRule ^([a-z][a-z])/([^/]+)(-.*)?$ /$2?ln=$1 [L]
They seem identical and both seem to work fine, but theres gotta be a difference...
Either of these should be installed to redirect with optional information behind the filename:
e.g. en/something-to-love
>> something?ln=en
The '.'
dot is overused and rarely needed. Say what you mean and mean what you say! Here's how I would write it:
RewriteRule ^([a-z]{2})/([^/\-]+)(-[^/]*)?$ index.php?ln=$1 [L]
While they might be similar, they're not identical:
.*?
- any character (lazy) or none,[^/]+
- any character except a slash (/
), at least one.
The second is not lazy, so you'll get something-to-love?ln=en
(to get only something
, add a question mark at the end: [^/]+?
).
The choice between these two options depends on your needs.
Btw, you can shrink [a-z][a-z]
to [a-z]{2}
.
There is a big difference. Let us test both expressions on the string aa/bbb/cccc/ddd/-eeeee. The first one
^([a-z][a-z])/(.*?)(-.*)?$
will result in three match groups
1: (aa)
2: (bbb/cccc/ddd/)
3: (-eeeee)
while the second one ^([a-z][a-z])/([^/]+)(-.*)?$
will not match anything.
The key is that in the first expression you have (.*?)(-.*)?
which means first group is anything until - is found. If - is matched then start the third group.
In the second expression you have ([^/]+)(-.*)?
, i.e., put everything till the / to the second group and then if - is matched, create a third group. The problem is with not matching / and starting new group with -.
If you test your second expression on two strings aa/bbb-/eeeee and aa/bbb/-eeeee you will see that only the first string will result in any matches
1: (aa)
2: (bbb)
3: (-/eeeee)
and the second will not.
Hope it helped.
Note: I have made all the mentioned tests at www.RegexTester.com.
Apache is lazy by default. So in rewrite .*
and .*?
are equal. That's why your [^/]+
is really [^/]+?
.
You have no / after the initial one, so [^/]
and .
produce the same result.
As of *
and +
, you know that you will surely have something after the en/
in your URL, so *
is just broader, it will always be +
(at least one character will follow the forward slash).
If you apply these facts its easy to see that they will work identically in your situation.
精彩评论