htaccess weird trailing slash problem - .htaccess

url: http://localhost/url/of/the/keyword/whatever/
RewriteRule ^url/of/the/keyword/([a-z]+)/?$ ?keyword=$1 [L]
// php
echo $_GET['keyword'];
// outputs **whatever** (OK)
RewriteRule ^url/of/the/keyword/(.*)/?$ ?keyword=$1 [L]
// php
echo $_GET['keyword'];
// outputs **whatever/** (with a trailing slash, which is not expected)
can anyone explain why there's a trailing slash for the second condition?
Also, how can I allow percentage sign in url rewrite?
http://localhost/url/of/the/keyword/%40%23%24/
RewriteRule ^url/of/the/keyword/([0-9a-zA-Z-.%])/?$ ?keyword=$1 [L]
the above rule doesn't work. can anyone correct this so it allows a-Z, 0-9, dot, hyphen, and percentage sign?
Thanks!

You are getting the / for the second RewriteRule because .* is greedy. That is to say it greedily captures the trailing slash because you've marked it as optional /?. It's best to be specific with your patterns (like the first RewriteRule) to avoid such situations.
The pattern you match can accept anything. Just remember it has to be a valid URL. The problem is you forgot the quantifier. So you're only matching one character from the grouping.
Add the +
RewriteRule ^url/of/the/keyword/([0-9a-zA-Z\-.%]+)/?$ ?keyword=$1 [L]

Related

Htaccess - Redirect if URL does not contain at least three numbers

I'm struggling to get this htaccess redirect to work. I want to redirect any URL that does not contain at least three numbers in a row. I started with the following and it worked perfectly for redirecting any URL that DID have three numbers in a row:
RewriteCond %{REQUEST_URI} [0-9]{3,20} [NC]
RewriteRule (.*) "https\:\/\/info\.mywebsite\.com\/" [R=301,L]
However, I tried to modify that with the exclamation mark to make the condition NOT match three numbers in a row:
RewriteCond %{REQUEST_URI} !([0-9]{3,20}) [NC]
RewriteRule (.*) "https\:\/\/info\.mywebsite\.com\/" [R=301,L]
But that doesn't seem to work as expected. Am I missing something with turning this expression into a not match?
Having previously experimented with the opposite 301 (permanent) redirect then the results are most probably cached (by the browser) from the earlier redirect. It is a good idea to test with 302 (temporary) redirects to avoid caching issues.
Note also that the REQUEST_URI server variable contains the URL-path only, so if the digits are contained in the query string part of the URL-path then your condition will fail.
The quantifier {3,20} matches from 3 to 20 characters, if you want "at least three" then use the quantifier {3,} (no upper bound).
You don't need the capturing subpatterns, ie. surrounding parentheses (...) on the regex since you are not using backreferences anywhere. Incidentally, you can't capture subpattern on a negated regex.
You don't need the additional condition (RewriteCond directive) - this can all be done with the RewriteRule directive only.
The NC flag is not required here - you are checking digits only.
For example:
RewriteRule !\d{3,} https://info.mywebsite.com/" [R=302,L]
As noted in comments, the RewriteRule substitution string is a regular string, not a regex, so does not require any special backslash escaping (although colons and slashes don't need escaping anyway in Apache regex).

I want to remove last slash and junk characters after valid url if url also contains a valid slash in htaccess using rewrite rule

for example
valid URL - https://stackoverflow.com/questions/question2
if the URL contains https://stackoverflow.com/questions/question2/dfjhasfu$#.
then i want to remove last slash and junk characters after valid URL
RewriteCond %{THE_REQUEST}!-d `RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.+?)/([a-zA-Z0-9\.\w\W\s]+)$ $1 [R=301,L,NE]
If your url guaranteed consists of just two parts, or "questions" followed by 1 part, you can use the following rule:
RewriteRule ^(questions/[^/]+)/ $1 [R,L]
You can replace "questions" with [^/]+ (1 or more non-slash characters) if you want. Change [R] to [R=301] after testing everything works as expected.

Htaccess rewrite index with trailing slash or without

I am currently having a problem with my index url rewrite in my .htaccess file, I know if I use
RewriteRule ^profile/([^/]*)/?$ /profile.php?x=$1 [L]
I would be able to use www.example.com/profile/get or www.example.com/profile/get/ (with or without trailing slash)
But I would like www.example.com/get what I have so far is
RewriteRule ^([^/]*)\/$ /index.php?x=$1 [L]
But if I put a ? before the $ it errors any answers welcome
Making the trailing slash optional will lead to an infinite loop, since [^/]* will match anything that doesn't include a /, ie it would also match index.php?x=get
You can avoid this by making the rule apply conditionally, for example by testing the reqeust URI:
RewriteCond %{REQUEST_URI} !^/index\.php.*
RewriteRule ^([^/]*)\/?$ /index.php?x=$1 [L]
That way the rule can only apply in case the request URI doesn't start with /index.php

mod_rewrite - check for string

I want to check if a URL contains the sting "-EN.htm", if so apply the rewrite.
That should be done with ^-EN.htm as follows, but the rule is not working:
RewriteCond %{REQUEST_URI} ^/(.*?)/([-_0-9a-zA-Z./=]*)^-EN.htm
RewriteRule ^(.*)$ /indexEN.php?folder=%1&follow=%2 [L]
What am I doing wrong?
Thank you for every help,
Scott
Your regular expression doesn't look right. You can also lose the condition and just move the pattern to the rewrite rule instead. Something along the lines of
RewriteRule ^/?(.*?)/([-_0-9a-zA-Z./=]*)^-EN.htm /indexEN.php?folder=$1&follow=$2 [L]
You need to make the leading slash optional (in htaccess this is stripped off) and instead of using % backreferences, use the $ ones.
Now on to your pattern, it's not valid. The ^ matches the beginning of the string (the URI), so if you have two of them and you're not trying to literally match the ^ character (which you'd need to escape), then the expression will never match anything. Without any examples of URLs that you're having to deal with, I assume you probably just want to ditch the second ^:
RewriteRule ^/?(.*?)/([-_0-9a-zA-Z./=]*)-EN.htm /indexEN.php?folder=$1&follow=$2 [L]

Do you have to escape a forward slash when using mod_rewrite?

With regards to the forward slash "/" when giving a regex to RewriteRule or RewriteCond, or anything else related to .htaccess in particular, is there a need to escape the forward slash?
Here is an example of what I am trying to achieve
RewriteEngine on
RewriteOptions inherit
RewriteBase /uk-m-directory/
RewriteRule ^(region|region\/|regions\/)$ regions [R=301,L]
RewriteRule ^(county|county\/|counties\/)$ counties [R=301,L]
RewriteRule ^(city|city\/|cities\/)$ cities [R=301,L]
The above works fine, and it continues to work fine when I remove the backslashes as shown below
RewriteEngine on
RewriteOptions inherit
RewriteBase /uk-m-directory/
RewriteRule ^(region|region/|regions/)$ regions [R=301,L]
RewriteRule ^(county|county/|counties/)$ counties [R=301,L]
RewriteRule ^(city|city/|cities/)$ cities [R=301,L]
Which one is the correct way? Are they both wrong?
Is there any special reason the forward slash should be escaped, or shouldn't?
My guess is that the forward slash does not need to be escaped because it isn't a special character, as far as I know. But I just want to be sure.
In case you're wondering the point of this code, it redirects city, county, and region (with or without a forward slash) to their plural equivalents. Furthermore if the plural has a forward slash it removes the forward slash.
No, you do not have to escape slashes. Forward slashes don't have any special meaning in regular expressions.
The one common character that has bitten me in the past is ? in query strings. That one you do have to escape.

Resources