开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜