Group literal string in htaccess regex pattern - regex

I need to rewrite URLs similar to
/b
to
/img/b.png
as well as URLs similar to
/b_c
to
/img/b_c.png
I have tried this:
RewriteRule ^b(?:/_c/)$ /img/$1.png
Which works for the first case but not the second (it is not matching "_c" and grouping it).
I need the literal string "_c" to be grouped and placed in the rewritten URL.
How can I accomplish this?

Try RewriteRule ^(b(_c)?)$ /img/$1.png.
This makes $1 the entire bracket backreference, and makes the _c optional, but it must be all there (you can't have b_ matching - though it can match if you want).

Related

PCRE based Regex for redirection

I have some links as follow.
http://www.example.com/excel.aspx
http://www.example.com:80/word.aspx
http://www.example.com:80/powerpoint.aspx
http://www.example.com:80/pdf.aspx
http://www.example.com:80/barcode.aspx
http://www.example.com/ocr.aspx
http://www.example.com/email.aspx
http://www.example.com/project.aspx
& I want to rewrite the URLs as following in a single regex pattern or single regex line.
https://www.example.com/excel
https://www.example.com/word
https://www.example.com/powerpoint
https://www.example.com/pdf
https://www.example.com/barcode
https://www.example.com/ocr
https://www.example.com/outlook
https://www.example.com/project
If you check & compare, I have replaced email with outlook in substitution URL.
I can match patterns as follow .*/(\w+).aspx and substitute as https://www.example.com/$1 but I cannot find a way to replace email with outlook. Demo https://regex101.com/r/71huIx/24
Something similar to http://www.rexegg.com/regex-trick-conditional-replacement.html but without a pool or dictionary. However, if the pool or dictionary can be part of regex itself then it will OK. Reason being, I have txt file with rules, where line1 is regex & line2 is a substitution.
Any ideas how can I do that?
Here's an Apache httpd config that should work:
RewriteEngine On
RewriteRule ^/outlook$ https://example.com/email.aspx [P,L]
RewriteRule ^/([^./])/?$ https://example.com/$1.aspx [P,L]
This uses a reverse proxy to serve pages like email.aspx and foobar.aspx when given "outlook" and "foobar" without revealing their extensions to users.
Though it looks like you're trying to go backwards for some reason. In that case, you'd want:
RewriteEngine On
RewriteRule ^/email\.aspx$ https://example.com/outlook [L]
RewriteRule ^/([^.]+)\.aspx$ https://example.com/$1 [L]
Regex conditional expressions cannot perform your task. The structure of a regex conditional is:
(?(condition)yes-pattern|no-pattern)
condition is either
a zero-width assertion (typically a lookahead)
a parenthesized integer, denoting whether that numbered capture has content
a capture group name in angle brackets or single quotes
(R) which is true when evaluated inside a recursion or eval
yes-pattern is a regex to match given the condition is true
no-pattern is an optional regex to match given the condition is false
Therefore, you can't shove new text into the match using a conditional.

htaccess - combine rewrites into single

I have a couple of RewriteRules that I'd like to combine into one. I'm not sure how to do it, though. I think look arounds would need to be used? The difference between the two is the first would match something like:
search/foo or search/foo/
and the second would match
search/foo/10 or search/foo/10/
Rewrites:
RewriteRule ^search/([a-zA-Z]+)/?$ index.php?page=search&query=$1&pn=1 [L]
RewriteRule ^search/([a-zA-Z]+)/([0-9]+)/?$ index.php?page=search&query=$1&pn=$2 [L]
Without using look arounds, my attempt would be
^search/([a-zA-Z]+)/?([0-9]+)?/?$
But i think that would match something undesirable like this?
search/foo10
edit:
I'm tryin to get the regex to match the following URIs:
search/foo
search/foo/
search/foo/1
search/foo/1/
^search/([a-zA-Z]+)(/)?([0-9]+)?\/?$
will this work? you might have make '/' also as match pattern and ignore $2.Same can be followed for the trailing '/' and ignore $4.

Htaccess regex to exclude everything except one string

I have done this: http://rubular.com/r/AHI15Tb4ju, and it match the second url (http://gamempire.localhost.it/news/tomb-pc), but I want to exclude that url and match everything that do not have the word "news/" inside (but at the same time end in the way that I have specified).
How to do that?
Basically, i want to match only the third url (http://gamempire.localhost.it/tomb-pc).
Thanks!
You can use a rule like this:
RewriteEngine On
RewriteCond %{REQUEST_URI} !/news/
RewriteRule -(?:pc|ps2|ps3|ps4|xbox-360|xbox-one|xbox|wii-u|wii|psp|ps-vita|ds|3ds|iphone|ipad|android|playstation)(.*)$ / [L,R]
Since I didn't know any action part I just redirected these matching URI patterns to / that you can change according to your need.
Try using this:
^((?!news).)*-(?:pc|ps2|ps3|ps4|xbox-360|xbox-one|xbox|wii-u|wii|psp|ps-vita|ds|3ds|iphone|ipad|android|playstation)(.*)$
It should be noted that I tried to modify your original pattern as little as possible, assuming you also needed the (.*) at the end even though it appears that this is unnecessary for your purposes, and would match strings such as
"http://gamempire.localhost-pc.it/tomb" and "http://-pcgamempire.localhost.it/tomb".

Complex regex in Apache rewrite rule

I am trying to create the following behavior with a rewrite rule.
https://domain.com/admin/user/add => /addedit.php?add=
https://domain.com/admin/user/add/ => /addedit.php?add=
https://domain.com/admin/user/add/123 => /addedit.php?add=123
https://domain.com/admin/user/add/123/ => /addedit.php?add=123
user is variable
add can either be "add" or "edit"
Trailing slashes are always allowed
There can be more after the slash after (add|edit) which is assigned to the variable
I'm fine up until the optional slash after the action word (add|edit). That's where I don't know regex well enough to accomplish my goal.
Something like the following works:
RewriteRule ^admin/(.*)/(add|edit)(/(.*)/?)?$ /admin/$1/addedit.php?$2=$3
However, the URLs end up containing the slashes in the GET variable. I figured I would be able to reference the (.*) in middle of (/(.*)/?)? as $4, but I am not.
I then read about non capturing groups and so added a ?: like so:
RewriteRule ^admin/(.*)/(add|edit)(?:/(.*)/?)?$ /admin/$1/addedit.php?$2=$3
It's probably a relatively simple thing I'm overlooking.
You're almost there, just minor modifications needed:
RewriteRule ^admin/([^/]+)/(add|edit)(?:/([^/]*))?/?$ /admin/$1/addedit.php?$2=$3 [L,NC]
Regex to match: ^(.*\/admin)(\/user)\/((?:add)|(?:edit))\/?(([^/]*)?\/?)$
Regex to replace: /addedit.php?$3=$5
http://regexr.com?36gp3

mod_rewrite rule using date regex

I'm trying to write a rule that when user types in this url:
domain.com/09/13/2013/thisIsMyPageTitle
That url stays in browser window, but content from this url is displayed:
domain.com/contentlibrary/thisIsMyPageTitle
This is my rule that I currently get an error with:
RewriteEngine On
RewriteRule ^((0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d[/])$(.*) /contentlibrary/$1 [L]
I'm trying to match the date with regular expression, and use the (.*) from the initial url in the second one that holds the content and actually exists.
If you're not going to do anything with date then why bother being precise with date semantics. You can simplify your regex:
RewriteRule ^[0-9]+/[0-9]+/[0-9]+/([^/]+)/?$ /contentlibrary/$1 [L]
The error that you're getting is probably because you have unescaped spaces in your regex. Specifically these:
[- /.]
The spaces get interpreted by mod_rewrite as the delimiter between parameters. Additionally, you have this:
$(.*)
at the end of your pattern. The $ matches the end of the string, so you want those swapped:
(.*)$
So:
^((0[1-9]|1[012])[-\ /.](0[1-9]|[12][0-9]|3[01])[-\ /.](19|20)\d\d[/])(.*)$
shold be the pattern that you want.