Forum Moderators: phranque

Message Too Old, No Replies

htaccess - rewrite IF +

         

rjbathgate

1:59 am on Jun 17, 2011 (gmt 0)

10+ Year Member



Hey,

I am trying to rewrite urls which have the + character in them to a given url.

For example, urls might look like

domain.com/ABC+DEF+ACE+1/
domain.com/GBGAD+ASDAH+6/
domain.com/GBGAD+AHBCGD/


I want to rewrite them to:

domain.com/redirect.php?string=[the string]

(e.g. domain.com/redirect.php?string=ABC+DEF+ACE+1)

I have other rewrite rules for other 'sub' directories etc, but ONLY these will have the + sign in them, so I'm hoping I can write a rule which makes use to something like ([A-Za-z0-9-.]+) BUT also has a check at at least one + sign exists in the url.


I hope this makes sense,

Thanks in advance
Rob

rjbathgate

2:00 am on Jun 17, 2011 (gmt 0)

10+ Year Member



EDIT: I mean redirect (301), NOT rewrite.

lucy24

7:31 am on Jun 17, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Be very careful. The + has to be escaped everywhere except inside [class] brackets. There is an enormous difference between

[A-Za-z0-9.]+

and

[A-Za-z0-9.]\+

(Your final - before . was an error. Incidentally, you can express the whole A-Za-z0-9 package as simply \w unless for some reason you need to exclude _ lowlines.)

The first version means "any number of alphanumerics and/or dots".

The second one means "an alphanumeric or dot followed by a literal plus sign".

Oh, and you can use a Rewrite statement to create a redirect. Just stick a [R=301,L] at the end of the rule. The advantage is that you can separate the condition(s)-- in this case, the request must contain a literal plus sign-- from the rule.

g1smd

8:11 am on Jun 17, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



RewriteRule with domain name in target and with [R=301,L] flags generates an external redirect.

RewriteRule without domain name in target and with [L] flag generates an internal rewrite.

The \w works only if Apache has been compiled with PCRE RegEx matching. For more portable code use [A-Z0-9] with the [NC] flag (POSIX matching).

rjbathgate

6:15 pm on Jun 17, 2011 (gmt 0)

10+ Year Member



Hey

Thanks for the replies... but I must admit I'm a bit of a layman, and don't totally understand from your replies what I need to do/write in my htaccess...

Cheers

rjbathgate

6:30 pm on Jun 17, 2011 (gmt 0)

10+ Year Member



Actually...

Done :)

Probably quite messy way of doing it, but it works as I want:

RewriteRule ^([A-Za-z0-9-.]+)\+([A-Za-z0-9-.]+) /redirect.php?one=$1&two=$2

(and then have it repeated for 3 elements, 4 elements and 5 elements).

Thanks

g1smd

6:53 pm on Jun 17, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Add the $ end anchor to the pattern and the [L] flag to the rule.

Yes. Repeat rules with longer patterns within each one.

[A-Za-z] can be replaced with [A-Z] when the [NC] flag is also used (parses 33% quicker too).

rjbathgate

7:04 pm on Jun 17, 2011 (gmt 0)

10+ Year Member



Hey,

Can you please explain what the $ end anchor will do?

And the [L] flag?

The redirects will be made on the same internal domain, i.e. www.domain.com/abc+def -> www.domain.com/abc-def

Thanks

g1smd

8:30 pm on Jun 17, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Without the end anchor the first rule will redirect the 3 element and 4 element requests too.

That's because the first rule will say 'redirect stuff that "begins with" 2 elements', and not 'redirect stuff that has "exactly" 2 elements'.

"begins with" means exactly that: "begins with" and may or may not have unspecified stuff following it.

The [L] flag stops processing here if this rule matches.

You should read a good RegEx and mod_rewrite tutorial. This stuff cannot be guessed at.

lucy24

9:11 pm on Jun 17, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



You should read a good RegEx and mod_rewrite tutorial.

I've yet to find something that lays out the exact rules for apache's specific RegEx dialect. (Apache themselves on the mod_rewrite page just point you to Perl.)

F'rinstance, \w works fine for me so I wouldn't have thought of not using it by default-- especially since I also have the occasional lowline in addresses but I'm antsy about hyphens. And it turns out the pattern [0-9-.] works in my text editor, though by The Rules it's a mistake and I'd expect an error message.

Conversely, they need to tell you that literal spaces have to be escaped, since spaces have meaning in rewrite and redirect statements. And people coming from a javascript background have to learn not to escape slashes and semicolons ;)

And then there are the 900 variations on \p{Alpha}, \P{ASCII} and so on where each dialect has its own preferred form.

g1smd

9:16 pm on Jun 17, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Yeah, it's a bit complicated and I mostly stick to using POSIX notation to make the code as portable as possible. PCRE is also allowed in Apache 2.2 onwards, and therefore doesn't work on Apache 1.x for example.

rjbathgate

12:52 am on Jun 18, 2011 (gmt 0)

10+ Year Member



Hey,

Thanks for all the help.

Have another little issue. I want to redirect any subdomains to the www.

Options +FollowSymLinks
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ^domain\.com
RewriteRule ^(.*)$ [domain.com...] [R=permanent,L]


This works absoutely fine for no www (i.e. domain.com), but doesn't do anything for subdomains (e.g. abc.domain.com).

What am I missing?

Thanks

g1smd

1:16 am on Jun 18, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



That's because your ^example.com pattern says "begins with example.com". Subdomains do not begin with that. Change the pattern, but don't let it match www.example.com itself.

rjbathgate

1:29 am on Jun 18, 2011 (gmt 0)

10+ Year Member



Hey,

How do I do that?

RewriteCond %{HTTP_HOST} ^abc\.domain\.com
RewriteRule ^(.*)$ [domain.com...] [R=permanent,L]

I would presume that means 'beings with abc.domain.com'

But it doesn't work...

Thanks

g1smd

1:34 am on Jun 18, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



That is the correct code for redirecting requests for the abc subdomain.

However, requests for that subdomain have to resolve to your server, so the first step is that abc must have a DNS entry in order to be "visible" on the web.

Use example.com to stop forum auto-linking.

rjbathgate

1:38 am on Jun 18, 2011 (gmt 0)

10+ Year Member



I was beginning to think I need to turn to the dns.

Thanks