Mod Rewrite help apache - turning pretty URLs into PHP acceptable links - regex

Right now I'm using this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([0-9a-zA-Z-]+)/?$ profile.php?userName=$1 [L]
This works for normal cases without spaces or underscores, etc... just the basics.
I need it to be pretty open to characters though - such as John_doe john-doe john doe.
I've tried a lot of other Regex's, but I can't seem to get one that works for everything. Much appreciate any help!
Thanks.

The . character will match any single character:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/?$ profile.php?userName=$1 [L]
Note the use of this regex is discouraged because of character encoding purposes (and SEO as well, but I don't know if it's relevant to you). It's always better to have addresses containing only lower case alphanumeric characters and dashes (-).
For more info about mod_rewrite regex, see this link.

Related

htaccess mod_rewrite server error

I try to make nice URLs with following htaccess entries:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([\w]+)/?([\w]+)?$ /index.php?subdir=$1&page=$2 (works fine)
#RewriteRule ^([^/]+)/?([^/]+)?$ /index.php?subdir=$1&page=$2 (doesn't work: 500 Int.Serv.Error)
(This one isn't much important to me, since, the first regex works, but if I understand this problem maybe the next problem I understand too)
So with the following line I'll try to get the rest of the query string
#RewriteRule ^(\w+)/?([\w]+)?(.*)$ /index.php?subdir=$1&page=$2&$3 (doens't work: 500 Int.Serv.Error)
Can someone explain, what I'm doing wrong? I have read something about that a wrong regex can create an endless loop. Maybe I've got one or two here?
Thanks in advance and regards
doc
The query string isn't available as part of the RewriteRule, you'd have to capture and examine it in separately in a RewriteCond %{QUERY_STRING} ...
However, you don't need to actually need to capture the rest of the query string in the rewrite, you can just use the QSA or Query String Append flag in your rule:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([\w]+)/?([\w]+)?$ /index.php?subdir=$1&page=$2 [QSA]

mod_rewrite .htaccess rewrite match with or without file extension

I'm using a php script to match request links to a site. I'm currently matching on 'jcole/' and 'jcole'. However I'd like to be able to match on "jcole"(.php|.html|.htm), "jcole/", and "jcole". I'd like the match to be agnostic of whatever the file extension maybe and also not care if there are periods in the name.(for example I'd like to be able to match on "j.cole")
Currently I have my .htaccess configured like so:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*\.html)$ /loadlink.php=link=$1 [L,QSA]
RewriteRule ^(.*)/?$ /loadlink.php?link=$1 [L,QSA]
You are way better off doing all of this from within php. Regex is not going to be able to do everything you want, especially having to deal with arbitrary periods in the name. So you'd just want the second rule:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ /loadlink.php?link=$1 [L,QSA]
Note that rewrite conditions only apply to the immediately following RewriteRule.
This will send everything to the "link" parameters, only removing an arbitrary trailing slash if it exists. It's up to the loadlink.php script to get rid of the .php or random periods in the name.

.htaccess RegEx for variable file version

I would like clients to be able to access certain files using an arbitrary version number to bypass caching.
For example, suppose there are two files: styles.css and jquery.min.js They should be able to request either the originals or styles.23.css and jquery.min.5039.css.
The rule I came up with was:
RewriteEngine On
RewriteRule ^(.*)\.(?!\..*)[\d]+\.(.*)$ $1.$2 # strip out version number
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
Broken down, here's my thought on what it should be doing:
^(.*) – starting from the beginning, match all
\. – up to the first period...
(?!\..*) - ...which is not followed by a period and anything,
[\d]+\. – then match if ends in one or more digits followed by a period...
(.*)$ – ...and anything
This RegEx actually works seems to work in PHP but not .htaccess, which has me a bit confused.
Thank you in advance.
Why do you need lookahead etc. Following should work:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+?)\.\d+\.(.*)$ $1.$2 [L]

Mod rewrite regex: How to allow only one period between other characters?

I am writing a mod rewrite rule to allow only one period between an arbitrary length characters. The characters must begin with a letter, followed by 2-29 characters or numbers, and allow only one period (optional) somewhere in the middle (but never in the end).
Here is what I have so far:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-z]([.a-z0-9]{2,29}))$ user.php?u=$1 [NC,QSA,L]
This rule is not working since it allows things like f.oo (valid), foo. (invalid), f.o.o (invalid), or even f.......
Is it possible to accomplish using just apache's mod rewrite? Or does the check have to be done in PHP or somewhere else?
Similar questions: this one and this one.
Thank you.
I couldn't do it in one rule, so I used two:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 ^.{3,30}$
RewriteRule ^([a-z][a-z0-9]*(?:\.[a-z0-9]+)?)$ user.php?u=$1 [NC,QSA,L]
I can't figure out how to do it in one regex, but you could stack your regex's
^[a-z][.a-z0-9]{2,29}$ #3-30 characters long, starting with a letter, then nums
^[a-z0-9]+\.?[a-z0-9]+$ #has zero or one dot in middle
updated to take numbers into account
http://regex101.com/r/nD2lI6
http://regex101.com/r/gR3vA1
So the full example should be something like:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^[a-z][.a-z0-9]{2,29}$
RewriteRule ^([a-z0-9]+\.?[a-z0-9]+)$ user.php?u=$1 [NC,QSA,L]

.htaccess regular expression issue

I still have no answer about this so I'm posting it here.
I want to match an url in the form of root/language/sub/.../document in a .htaccess file and then rewrite it as root/sub/.../document.php?lang=language
Im close to hit but it seems my regexp doesn't 'catch' the input url. Here it is :
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond ^[a-z]{2}.*$/%{REQUEST_FILENAME}\.php -f
RewriteRule ^([a-z]{2})/(.*)$ $2.php?lang=$1
Can someone point me out what is wrong here ? I'm no expert in regexp nor apache rewrites.
Tyvm
* EDIT *
root stands for domain ie mydomain.net
Here are a few examples :
mydomain.net/fr/contact
should be rewriten to
mydomain.net/contact.php?lang=fr
and
mydomain.net/en/articles/view
should be rewriten
mydomain.net/articles/view.php?lang=en
etc...
I believe you are looking for this configuration:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} ^(.*/|)(en|de|fr)/(.*)$ [NC]
RewriteCond %1%3.php -f
RewriteRule ^(.*/|)(en|de|fr)/(.*)$ $1$3.php?lang=$2 [NC,QSA,L]
Explanation:
RewriteCond %{REQUEST_FILENAME} !-d
Checks if requested url is not a directory. If yes, no rewriting will be processed.
RewriteCond %{REQUEST_FILENAME} ^(.*/|)(en|de|fr)/(.*)$ [NC]
Checks if url contains /xx/ part inside, where xx is one en, de or fr. Flag [NC] allows uppercase and lowercase charactes, so for example EN or Fr will be accepted. If there is no such "language" part in the url, no rewriting will be processed.
RewriteCond %1%3.php -f
Checks if %1%3.php file exists, where %1 is (.*/|) and %3 is (.*) matches from the previous RewriteCond ^(.*/|)(en|de|fr)/(.*)$. If such php file does not exist, no rewriting will be processed.
RewriteRule ^(.*/|)(en|de|fr)/(.*)$ $1$3.php?lang=$2 [NC,QSA,L]
In the RewriteRule left condition will be matched if it came to this line, as it was already checked with RewriteCond, so now it will process rewriting to php file, adding lang part, but because there is also [QSA] flag, it will keep also other GET parameters, so lang will be added to existing parameters. Flag [L] says it is last rewriting rule that should apply and no more rewriting will be processed with this url.
Well I'm not sure what root is doing in there, have you tried
RewriteRule ^root/([a-z]{2})/(.*)$ root/$2.php?lang=$1
What's wrong is the second RewriteCond. But your question is vague. If you mean you're trying to convert
root/foo/sub/.../something.php
to
root/sub/.../something.php?lang=foo
then start fidgeting with this:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^root/([^/]+)/sub/(.*)/%{REQUEST_FILENAME}$ root/sub/$2/%{REQUEST_FILENAME}?lang=$1