URL Rewriting in .htaccess - getting confused with params - regex

I searched in the web to find a valid solution for my problem, but nothing works.
Hopefully you guys can help me.
I want to Rewrite a URL on an Apache doing like that:
(1.) www.example.com/en/rainbow.html => www.example.com/index.php?site=rainbow&lang=en
or
(2.) www.example.com/rainbow.html =>www.example.com/index.php?site=rainbow&lang=
or
(3.) www.example.com//rainbow.html =>www.example.com/index.php?site=rainbow&lang=
To be honest, my understanding for regex isn't that good.
Tried:
RewriteEngine On
RewriteRule ^(.+)[/](.+).html|(.+).html$ index.php/?lang=$1&site=$2 [QSA]
Result: No Error, but "site" has only a param at (1.).
RewriteEngine On
RewriteRule ^(.*[/]){0,1}(.*).html$ index.php/?lang=$1&site=$2 [QSA]
Result: Works fine, but i.e. lang="en/", should be lang="en"
In which way I can improve it and let it work correct?!
Thanks a lot!!

Try this:
RewriteEngine On
RewriteRule (/en/)?([^/]+)\.html$ index.php/?site=$2lang=$1 [QSA]
No need to escape forward slashes in mod-rewrite, by the way. But you do need to escape the ., which, as you know, stands in as a wildcard in regular expressions.

I'm not an expert in url rewriting, but i like koalas:
RewriteRule /+(([^/]+)/)?([^/]+)\.html$ /index.php/?site=$3&lang=$2 [QSA]

Related

Remove a part of the URL using REGEX and .htacess

I want to replace this URL:
mydomain.com/posts/1659-artigos/etc-to
By this one:
mydomain.com/etc-to
Using .htaccess I'm trying the following:
RewriteEngine on
RewriteRule ^posts/1659-artigos/(.*)$ $1
But it isn't working. No redirect happens.
Can anyone help?
Thanks!
Converting my comment to answer so that solution is easy to find for future visitors.
You can use this code to get redirect working:
RewriteEngine on
RewriteRule ^posts/1659-artigos/(.*)$ /$1 [L,R=301,NC]
You need to use / before $1 for external redirect and make sure to use R flag for full redirect.

How to write expression to grab all after an expression and then rewrite in htaccess

I'm new to the rewriting of urls and regex in general. I'm trying to rewrite a URL to make it a 'pretty url'
The original URL was
/localhost/house/category.php?cat=lounge&page=1
I want the new url to look like this:
/localhost/house/category?lounge&page=1
(like I say, I'm new so not trying to take it too far at the moment)
the closest I've managed to get it to is this:
RewriteRule ^category/(.*)$ ./category.php?cat=$1 [NC,L]
but that copies the whole URL and creates:
/localhost/house/category/house/category/lounge&page=1
I'm sure, there must be an easy way to say copy all after that expression, but I haven't managed to get there yet.
I will try to help you:
You probably have already, but try a mod rewrite generator and htaccess tester.
From this answer: The query (everything after the ?) is not part of the URL path and cannot be passed through or processed by RewriteRule directive without using [QSA].
I propose using RewriteCond and using %1 instead of $1 for query string matches as opposed to doing it all in RewriteRule.
For your solution, try:
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^house/category$ house/category.php?cat=%1 [NC,L]
This will insert the .php and cat= while retaining the &page=
Anticipating your next step, the below mod rewrite may help get started in converting
http://localhost/house/category/lounge/1
to
http://localhost/house/category.php?cat=lounge&page=1
Only RewriteRule necessary here, no query string:
RewriteRule ^house/category/([^/]*)/([0-9]*)/?$ house/category.php?cat=$1&page=$2 [NC,L]
Use regex101 for more help and detailed description on what these regexes do.
If it still not working, continue to make the regex more lenient until it matches correctly:
Try to remove the ^ in RewriteRule so it becomes
RewriteRule category$ category.php?cat=%1 [NC,L]
Then it will match that page at any directory level. Then add back in house/ and add /? wherever an optional leading/trailing slash may cause a problem, etc.
Thanks for all your suggestions, I took it back to this
RewriteRule category/([^/])/([0-9])/?$ category.php?cat=$1&page=$2 [NC,L]
which has done the trick, and I'll leave it at this for now.

Rewrite rule regexp

I would like to ask you guys because I have a problem with one my rewrite rules and I can't figure it out how to write the good one.
I have this rule:
RewriteRule ^wp-content/uploads/(.*[^(.js|.swf)])$ authenticate.php?file=$1
What I would like to do is redirect the user to the authenticate.php every time when someone tries to open something in the wp-content uploads dir and I would like to send the filename to the php
For example:
http://domain.tld/wp-content/uploads/2015/11/something.pdf
redirect to authenticate.php?file=something.pdf
But unfortunately my regexp is broken. Could someone help me?
Really thanks for it!
Try with that in your .htaccess:
RewriteCond %{REQUEST_URI} !(?:js|swf)$ [NC]
RewriteRule ^wp-content/uploads/(.+)$ authenticate.php?file=$1 [NC,L]
For http://domain.tld/wp-content/uploads/2015/11/something.pdf the result: http://domain.tld/authenticate.php?file=2015/11/something.pdf
Try using this regex with negative lookaheads:
^.*?wp-content\/uploads\/.*?\.(?!js$|swf$)[^.]+$
The following URL will match the regex:
http://cpsma.ie/wp-content/uploads/2015/09/CPSMA-Newsletter-No-35-Sept-2015-2.pdf
However, a similar URL which ends in .js or .swf will not match. Hence, the following two URLs do not match the regex:
http://domain.tld/wp-content/uploads/2015/10/javascript.js
http://domain.tld/wp-content/uploads/2015/02/shockwavefile.swf
You can test this regex out here:
Regex101

Regular expression for referrer redirection

I need the regular expression to redirect a link like this:
www.mysite.com/forums/users/tom
To: http://www.mysite.com/dashboard/listings/tom
The problem is that the script I am using constructs links like this:
www.mysite.com/forums/users/tom/favorites/
And I need to redirect ONLY the www.mysite.com/forums/users/tom and NOT the www.mysite.com/forums/users/tom/favorites/ which I would like to leave as it is.
Is there any way to do this?
Please help me. :(
This should work and only redirect mysite.com/referrer/ and not mysite.com/referrer/topic:
RewriteEngine on
RewriteRule ^referrer/$ http://someurl.com [L,R=301]
EDIT:
RewriteEngine on
RewriteRule ^forums/users/(.*)/?$ http://www.mysite.com/dashboard/listings/$1 [L,R=301]

Understanding RegEx - SEO Duplication on last term

i have a problem with duplicate pages for SEO on a website i'm trying to fix. www.example.com/category/c1234 loads just the same as www.example.com/category/c1234garbage
I've been reading online and testing the code and so far I narrowed it down to a possible regex problem. I have the following lines
# url rewrites
RewriteCond %{REQUEST_URI} ^/index\.cfm/.+ [NC]
RewriteRule ^/index.cfm/(([^/]+)/?([^/]+)?)/?(.*)? /index.cfm/$4?$2=$3 [NS,NC,QSA,N,E=SESDONE:true]
I added an R in the rule so I could see if it was passing through there and it is and after it passes that the garbage at the end disappears.
Can someone help me understand this and figure out a way to fix it so when you go to www.example.com/category/c1234garbage it redirects to www.example.com/category/c1234
I've been searching online for quite a while now and thought it might be time to post here since I can't seem to find a solution. I'm reading "Mastering Regular Expressions" but it might take take a while for me to find the answers I'm looking for.
I appreciate any help you can give me. Thank you.
EDIT: This is what i have before that
RewriteEngine On
Rewritebase /
# remove trailing index.cfm
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^index.cfm(\?)?$ / [R=301,L]
# remove trailing slash
RewriteCond %{QUERY_STRING} ^$
RewriteRule (.*)/$ /$1 [R=301,L]
# Remove trailing ?
RewriteCond %{THE_REQUEST} \?\ HTTP [NC]
RewriteRule ^/?(index\.cfm)? /? [R=301,L]
# SEF URLs
SetEnv SEF_REQUEST false
RewriteRule ^[a-z\d\-]+/[a-z]\d+/? /index.cfm/$0 [NC,PT,QSA,E=SEF_REQUEST:true]
RequestHeader add SEF-Request %{SEF_REQUEST}e
RewriteCond %{HTTP:SEF_REQUES} ^true$ [NC]
RewriteRule . - [L]
EDIT: I was reading the htaccess again and found this that I don't understand but it might have some connection. It's located at the bottom of the file.
# lowercase the hostname, and set the TLD name to an enviroment variable
RewriteCond ${lowercase:%{SERVER_NAME}|NONE} ^(.+)$
RewriteCond %1 ^[a-z0-9.-]*?[.]{0,1}([a-z0-9-]*?\.[a-z.]{2,6})$
RewriteRule .? - [E=TLDName:%1]
From your description and your code, it sounds like this is the transformation that's happening here:
www.example.com/category/c1234garbage
↓
www.example.com/index.cfm?category=c1234garbage
So the problem, I think, is not your rewriting rules. The problem is how you're handling querystring parameters on the server side. If you have an actual page called index.cfm that's interpreting those parameters, you should tweak the code behind that page to validate them and redirect to /category/c1234 where appropriate.
I think the code in index.cfm is looking at the parameter, checking to see if it starts with something recognizable, and going from there. You need to make it more strict.
Alternatively, you could add another .htaccess rule to parse the c1234garbage part and decide which part is valid, and which part (if any) is garbage. I can't give you a regex for that, though, since I don't know the rules for a valid input in your application.
Edit:
I think I found the problem. This part here:
RewriteRule ^[a-z\d\-]+/[a-z]\d+/? /index.cfm/$0 [NC,PT,QSA,E=SEF_REQUEST:true]
You specify the beginning of the relative URL with ^, but you don't specify that you want it to match all the way to the end. So I think what's happening is that it's taking the part of the string that matches, throwing out everything else, and appending it to /index.cfm/. So it takes only the /category/c1234 part from /category/c1234garbage, because that's the part that matches ^[a-z\d\-]+/[a-z]\d+/?.
You can probably fix this with just a word break:
RewriteRule ^[a-z\d\-]+/[a-z]\d+\b/? /index.cfm/$0 [NC,PT,QSA,E=SEF_REQUEST:true]
If that doesn't work, I'm afraid we've reached the end of my htaccess knowledge. I'm more of a regex guy.
Just BTW, this still seems a little awkward. If I understand this right, part of the URL will still get thrown out if it doeesn't fit your exact pattern. E.g. /category/c1234?abc=123 will lose its querystring parameters. You might want to redesign how your rules are set up.
I partially solved the problem. I added
# Remove garbage from after category
RewriteCond %{REQUEST_URI} [a-z\d\-]+/[a-z]\d+(.+)
RewriteRule ^([a-z\d\-]+/[a-z]\d+)/? $1 [R=301]
on top of the SEF rules. It's doing what i want which is to remove the garbage from the url but it gives me an infinite loop because its redirecting even when the url is clean. Any hints?
EDIT: So i realized that the .+ at the end is matching the numbers as well... How do i change it to match anything other than numbers after the numbers? basically where I have the .+ i need to have a "match any character except for numbers"
EDIT: I finally got it to work with the following code:
# Remove garbage from after category
RewriteCond %{REQUEST_URI} [a-z\d\-]+/[a-z]\d+[A-Za-z-.]+
RewriteRule ^([a-z\d\-]+/[a-z]\d+)/? $1 [R=301]
The (.+) i was using previously was reading the 2nd number (c1234)as being part of the . so it would always pass the the condition as true unless it was something like c1