Matching URI with regex find replace - regex

I'm still learning Regex operations and I couldn't figure out how I can execute a regex that replace in a URI the "/" with "-" in an Apache rewrite rule expression. Assuming that It would be possible for as many "/" as existing in the incoming URI.
I tried ^\/?(([a-z0-9_\.-]+)\/)+$ and tested with $1-$2 for example1/example2 but i didn't work.
Can anyone help me with this ?
Thanks

The following lines in mod_rewrite in .htaccess in the root folder, or in the vhost configuration file in your Apache :
RewriteEngine On
RewriteRule (.*)([^\/]+)\/([^\/]+)\/?$ http://%{HTTP_HOST}$1$2-$3
will rewrite
http://%{HTTP_HOST}/example1/example2
as
http://%{HTTP_HOST}/example1-example2
and
http://%{HTTP_HOST}/example1/example2/example3/example4
as
http://%{HTTP_HOST}/example1-example2-example3-example4

Why not just use
\/ '-'
preferably with the 'g' flag to replace every slash in the Uri. That way (in javascript)
"example1/example2".replace(/\//, '-');
returns
"example1-example2"

Related

remove first folder in nginx

I have some URLs like:
http://example.com/username/file.zip
http://example.com/username/videos/aaa.avi
http://example.com/username/videos/abc/asdfdef/aaa.avi
the real path of files are:
/file.zip
/videos/aaa.avi
/videos/abc/asdfdef/aaa.avi
so basically I need to remove first folder in the URL
I tried to use this rewrite rule :
rewrite ^/.*/(.*)$ /$1 last;
but its remove all folders and grep just the filename, it's work just for first URL and i get 404 error for rest of them
- P.S: the username could be anything
i didnt test it but based on that nginx uses pcre library i think
rewrite ^/.*?/(.*)$ /$1 last;
would work.
.*? matches any character between zero and unlimited times, as few times as possible, expanding as needed (lazy)

Rewrite URL condition - Change particular string & remove trailing numbers

What's the best way to rewrite URLs as 301 redirects with the following conditions?
Sample old URLs to rewrite:
/c/garments-apparel/red-yellow-polka-dress-10_450
/c/shoes-and-accessories/black-suede-boots-02_901
Conditions:
Change c to category
Remove trailing number (including connecting dash) from URL (example: -10_450 and -02_901)
New URLs should be:
/category/garments-apparel/red-yellow-polka-dress
/category/shoes-and-accessories/black-suede-boots
Note that changes will be applied to an .htaccess file on a Wordpress environment.
You can have this rule just below RewriteEngine On line:
RewriteEngine On
RewriteRule ^c/([\w-]+/.+)-[\d_]+/?$ /category/$1 [L,NC,R=301]
you can use the regex
[-_]\d+
to replace the trailing numbers with "" (empty string) demo
then use the regex
\/c\/
and replace with /category/ demo

Apache2: Rewrite url containing question mark

I am using Apache 2.4.7. I use mod_rewrite to alter some urls.
I want to rewrite http://example.com/servicename/oldpage?id=abcto http://example.com/servicename/newpage.
Other similar rewrites work so I belive the ? inside url is causing problems.
I have tried escaping it with \.
This works as there is no ? in url:
RewriteRule ^/servicename/old /servicename/new
But these don't work:
RewriteRule ^/servicename/oldpage?id=abc /servicename/newpage
RewriteRule ^/servicename/oldpage\?id=abc /servicename/newpage
I have also tried using RewriteCond from examples like this: .htaccess rewrite URL with a question mark "?" but I didn't manage to get them work.
How should rewrite url that contains question mark?
EDIT: I tried solutions given in Match Question Mark in mod_rewrite rule regex but was not able to make them work for me. That question is about preserving query string when rewrite while I want to remove it when rewriting.
RewriteRule pattern is matched against the part of the URL after the hostname and port, and before the query string.
When the requested URI contains a query string, and the target URI does not, the default behavior of RewriteRule is to copy that query string to the target URI. Using the [QSD] flag causes the query string to be discarded.
So, this should work:
RewriteRule ^/servicename/oldpage /servicename/newpage [QSD]

Unknown number of regex replacements, how?

I need to change a large number of URIs in the following way:
substitute %20 separators with dashes -,
substitute the old root with a new domain.
Examples:
/old_root/first/second.html -> http://new_domain.com/first/second
/old_root/first/second%20third.html -> http://new_domain.com/first/second-third
/old_root/first/second%20third%20fourth.html -> http://new_domain.com/first/second-third-fourth
The best I came up with using regex is to write as many pattern-replacement rules as the maximum number of %20 separators that can occur in my URIs:
old_root/(.*?)/(.*?)\.html -> http://new_domain.com/$1/$2
old_root/(.*?)/(.*?)%20(.*?)\.html -> http://new_domain.com/$1/$2-$3
old_root/(.*?)/(.*?)%20(.*?)%20(.*?)\.html -> http://new_domain.com/$1/$2-$3-$4
My question is: is it possible to obtain the same result using a single regular expression rule?
I thought I could use a two-step approach: first change all %20 separators to - and then use the rule old_root/(.*?)/(.*?)\.html -> http://new_domain.com/$1/$2/. However, I need to apply this rule in a .htaccess file as a RedirectMatch directive and, as far as I know, it is not possible to use two successive rules for the same redirect directive.
It turns out that Apache recursively applies all regex rules until they stop matching. Therefore, I am allowed to write two rules rather than one to solve my problem.
The following rules do what I was looking for, and more; I have tested them on my local Apache server and they work fine. Note that for them to work, you need to first turn on the rewrite engine by prepending
RewriteEngine on
Options +FollowSymlinks -MultiViews
in the local .htaccess file or in the global httpd.conf file.
Replace all spaces with hyphens
Replace both literal spaces and %20 with hyphens:
RewriteRule ^(.+)(\s|%20)(.+)$ /$1-$3 [R=301,NE,L]
Replace all apostrophes with hyphens
Replace all literal apostrophes and %60 with hyphens:
RewriteRule ^(.+)('|`|%60)(.+)$ /$1-$3 [R=301,NE,L]
Delete the trailing .html extension
RewriteRule (.+)\.html$ $1 [R=301,L]
Convert the last field in the URL to lower case
Convert the last field in the URL to lower case and prepend the new domain:
RewriteRule /whatever/(.*?)/(.*?)/(.*) http://new.domain.com/$1/$2/${lc:$3} [R=301,L]
Important: The lowercase conversion will only work if you include the following lines at the end of the Apache configuration file httpd.conf, which is usually located in the etc directory on the server:
RewriteEngine on
RewriteMap lc int:tolower
A last note: I recommend prepending each rule with a RewriteCond directive to restrict the field of application of the rule. For example, to apply the space-to-hyphens rule only to those URI that match a certain regex, you should write the following in your .htaccess file:
RewriteCond %{REQUEST_URI} regex_for_URIs
RewriteRule ^(.+)(\s|%20)(.+)$ /$1-$3 [R=301,NE,L]
where regex_for_URIs is the regular expression that the URI must match in order for the next RewriteRule to be applied; it can also be a simple string.
Well, you were almost done.
Problems
Don't return "%20" - We'll Use them as "delimiter" of parts of the path
Add condition on third & fourth group (because you might pass short URL i.e. your examples)
Solution
\/old_root\/(.*?)\/(\w*)(?:%20)?(\w*)?(?:%20)?(\w*)?\.html
See Demo
Explanation
(?:%20)? means "%20" is non catching group that can occurs 0 or 1 time.
Same logic applyies on possible 3rd & 4th part.

How to check for dot(.) in mod_rewrite

I want to redirect URL
domain/Family_He..
to
domain/Family_Health_insurance
using RewriteRule. I have tried with
RewriteRule /Family_He(.*)$ /Family_Health_insurance
and it is working. But I have some more page with urls like
domain/Family_Health_info
domain/Family_Health_quote
domain/Family_Health_child etc
When I tried as
RewriteRule /Family_He\.\.$ /Family_Health_insurance
then this won't works for me. Please help me out.
Are you aware that there are actually two spaces at the end of your subject string that would prevent \.$ (a literal dot at the end of the string) from matching?
To have it redirect (302) you need to add the R flag. To match the dot you need to escape it using \. like
RewriteRule ^/Family_He\.\.$ /Family_Health_insurance [R=302,L]
Note that the leading slash doesn't work in htaccess, only in httpd.conf