Regex in rewerite rule in .htaccess - regex

I'm trying to redirect some urls of my old website after my migration , urls that need to be redirected are:
first block:
/fr/YYYY/mm/dd/
/fr/YYYY/mm/
/fr/YYYY
target:
blog/
Second block:
/fr/tag/tag1
/fr/tag/tag4
/fr/tag/tag3
/fr/tag/tag2
target:
blog/targetpage
Third block
fr/categorie/categoryName/
target
blog/categoryName
For the first block I tried the following:
RewriteRule ^fr/d{4}/(.*) /blog [R=301]
It does only work for pattern like: fr/2015 but not fr/2015/12/02
I tried another regex https://regex101.com/r/4oZpxX/1 but I do not how to write it htaccess style.
Could please help me with this, thanks in advance.

For your first block, \/fr\/(\d{4})\/?(\d{2})?\/?(\d{2})? will recognize all of those date formats correctly.
\d{#} recognizes a string of # digits
? after \/ and \d{#} makes them optional
For the second and third block I need more information about what kind of strings the "tags" and "categories" are.

Related

Redirect the URL from one query string to another

I have spent a great many hours trying to find a solution to this and tried many different approaches but nothing I have tried has worked so far.
I would like to redirect a URL with a query string to another URL that contains the value of that query string.
I want to redirect:
https://example.com/component/search/?searchword=XXXXXXXXX&searchwordsugg=&option=com_search
to
https://example.com/advanced-search?search=XXXXXXXXX
You can do something like the following using mod_rewrite at the top of your root .htaccess file:
RewriteEngine On
RewriteCond %{QUERY_STRING} (?:^|&)searchword=([^&]*)
RewriteRule ^component/search/?$ /advanced-search?search=%1 [NE,R=302,L]
The RewriteRule pattern matches against the URL-path only, which notably excludes the query string. To match against the query string we need a separate condition that checks against the QUERY_STRING server variable.
%1 is a backreference to the first capturing group in the preceding CondPattern, ie. the value of the searchworld URL parameter.
The regex (?:^|&)searchword=([^&]*) matches the searchworld URL parameter anywhere in the query string, not just at the start (as in your example). This also permits an empty value for the URL parameter.
The NE flag is required to prevent the captured URL parameter value being doubly encoded in the response. (Since the QUERY_STRING server variable is not %-decoded.)
The L flag prevents further processing during this pass of the rewrite engine.
Reference:
Apache docs: RewriteRule Directive
Apache docs: RewriteCond Directive

How to redirect using htaccess and regex the middle part of URLs leaving the dynamic end as is?

I need to redirect a lot of URLs by changing just some part that is in the middle or at the end of the URL. If that part is in the middle, the end must stay the same.
I need to accomplish this by using htaccess and regex.
I found a lot of examples online, but most of the are one on one redirection, and not covering enough dynamic websites. Also I haven't found answer to this in other questions here.
I have URL:
www.domain.com/something (alone) OR URLS like
www.domain.com/something-aaa-bbb-ccc OR only
www.domain.com/something-aaa
How to make it:
www.domain.com/somethingELSE but ALSO:
www.domain.com/somethingELSE-aaa-bbb-ccc
(KEEP aaa-bbb or whatever goes at the end the same)
To make this more human readable, let's say these are shops with a lot of locations:
www.domain.com/my-shop - Without anything else after OR:
www.domain.com/my-shop-belgrade ... or
www.domain.com/my-shop-new-york ... or ... shop-wherever-wherever-wherever
TO BE:
www.domain.com/my-office - Without anything else after OR:
www.domain.com/my-office-belgrade ... or
www.domain.com/my-office-new-york ... or ... my-office-wherever-wherever-wherever
The following was my urgent solution, but it's not dynamic, and it only covers 2 examples, but I need solution for the dynamic website, the solution that covers all the above.
<IfModule mod_rewrite.c>
RewriteEngine On
Redirect 301 /my-shop /my-office
Redirect 301 /my-shop-new-york /my-office-new-york
</IfModule>
This is the solution that worked out for me.
In order to replace the leading /my-shop with /my-office and leave everything afterwards as is, I used a capturing group:
(.*)
and replaced it with $1:
RedirectMatch 301 /my-shop(.*) /my-office$1

htaccess dynamic target using regular expressions

Hi I want to create a rule to remove the first directory on the url, see the example:
request url: http://www.example.com/San-Salvador/help
I want to redirect that to
Target url: http://www.example.com/help
the pattern is [base url][city name][directory] and I want to recreate it as this [base url][directory name]
Here is a general regex which should work:
^(http:\/\/www\.example\.com\/)(.*\/)(.*)
Each term in parentheses is a group which will potentially match an input string. For the input string:
http://www.example.com/San-Salvador/help
here are the matching groups:
http://www.example.com/
San-Salvador/
help
The groups you want to retain are the first and third ones, i.e. http://www.example.com/ and help to give you http://www.example.com/help
You can explore this regex here at Regex 101.
For the most part this is a rule that you can use to remove the city. However your code will need to handle what happens after the redirected URL is requested. Meaning what is displayed when this is called http://www.example.com/help
RewriteEngine on
RewriteRule ^(?:[^/]+)/([^/]+)/?$ /$1 [L]

Redirect all URLs starting with STRING that does NOT include a SUBSTRING

I need some help with regex.
I'm building some 301 rules for an .htaccess
I need to redirect all urls starting with a specific string excluding one that has a given word in the match-all part
this is the simple rule I'm using:
/my/sample/url/(.*)
I need to edit the (.*) part to say: anything except if contains "foobar"
if contains "foobar" I need a different 301 rule
This looks like is working:
^(?!.*foobar)/my/sample/url/(.*)
does anybody have a better solution?

How to rewrite this URL to a redirect page?

I am using Microsoft-IIS/7.5 on a hosted server (Hostek.com)
I have an existing site with 2,820 indexed links in Google. You can see the results by searching Google with this: site:flyingpiston.com Most of the pages use a section, makerid, or bikeid to get the right information. Most of the links look like this:
flyingpiston.com/?BikeID=1068
flyingpiston.com/?MakerID=1441
flyingpiston.com/?Section=Maker&MakerID=1441
flyingpiston.com/?Section=Bike&BikeID=1234
On the new site, I am doing URL rewriting using .htaccess. The new URLs will look like this:
flyingpiston.com/bike/1068/
flyingpiston.com/maker/1123/
Basically, I just want to use my htaccess file to direct any request with a "?" question mark in it directly a coldfusion page called redirect.cfm. On this page, I will use ColdFusion to write a custom 301 redirect. Here's what ColdFusion's redirect looks like:
<cfheader statuscode="301" statustext="Moved Permanently">
<cfheader name="Location" value="http://www.newurl/bike/1233/">
<cfabort>
So, what does my htaccess file need to look like if I want to push everything with a question mark to a particular page? Here's what I have tried, but it's not working.
RewriteEngine on
RewriteRule ^? /redirect.cfm [NS,L]
Update. Using the advice from below, I am using this rule:
RewriteRule \? /redirect/redirect.cfm [NS,L]
To try to push this request
http://flyingpiston2012-com.securec37.ezhostingserver.com/?bikeid=1235
To this page:
http://flyingpiston2012-com.securec37.ezhostingserver.com/redirect/redirect.cfm
There's a couple of reasons what you're trying isn't working.
The first one is that RewriteRule uses a regex, and ? is a regex metacharacter, which therefore needs be escaped with a backslash (\?) to tell it to match the literal question mark character.
However, the second part of the problem is that the regex for RewriteRule is only tested against the filename part of the URL - it specifically excludes the query string.
In order to match against the query string you need to use the RewriteCond directive, placed on the line before the rule (but applied in between the RewriteRule matching and replacing), acting as an additional filter. The useful bit is that you can specify which part of the URL to match against (as well as having the option for using non-regex tests).
Bearing all this in mind, the simplest way to match/rewrite a request with a query string is:
RewriteCond %{QUERY_STRING} .
RewriteRule .* /redirect/redirect.cfm
The %{QUERY_STRING} is what the regex is tested against (everything in CF's CGI scope can be used here, and some other stuff too - see the Server Variables box in the docs).
The single . just says "make sure the matched item has any single character"
At the moment, this rule will preserve the existing query string - if you want to discard it, you can place a ? onto the end of the replacement URL. (If you need to use a query string on the URL and not discard the old version, use the [QSA] flag.)
In the opposite direction, you're losing the filename part of the URL - to preserve this, you probably want to append it onto the replacement as PATH_INFO, using the automatic whole-match capture $0.
These two things together provides:
RewriteCond %{QUERY_STRING} .
RewriteRule .* /redirect/redirect.cfm/$0?
One final thing is that you'll want to guard against infinite loops - the above rule strips the query string so it will always fail the RewriteCond, but better to be safe (especially if you might need to add a query string), which you can do with an extra RewriteCond:
RewriteCond %{QUERY_STRING} .
RewriteCond %{REQUEST_URI} !/redirect/redirect\.cfm
RewriteRule .* /redirect/redirect.cfm/$0?
Multiple RewriteCond are combined as ANDs, and the ! negates the match.
You can of course add whatever flags are required to the RewriteRule to have it behave as desired.