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
Related
I am redirecting certain urls with path to get variables like the following:
localhost2/post/myTitle => localhost2/post.php?title=myTitle
localhost2/post/123 => localhost2/post.php?id=123
So In my htaccess file, I use
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^post/(\d+) post.php?id=$1
RewriteRule ^post/(.*) post.php?title=$1
</IfModule>
This works no problem. But I want to learn how to write negative of ^post/(\d+), that is ^post/(NEGATE-ONLY-NUMBERS). In other words I want a regex that matches the whole input sting if there is not only numbers after post/. So post/abc, post/a23, post/ab3, post/12c and post/a2c should all pass but not post/123. I refered to this post, which suggest using:
(?!^\d+$)^.+$
I can't use ^post/(?!^\d+$)^.+$, because there can be only one ^ and one $. I don't know what regex anchor specifies first position in a substring. My best guess is
post\/(?!\d++).*
I think (?!\d++), with the ++ would eat all characters followig and check if all are digits. But this fails at post/1ab.
Another guess is:
post\/(?![\d,\/]+$).*
The works the best but it allows: post/3455/X.
Secondly, eventually I need to convert localhost2/post/myTitle/123 => localhost2/post.php?title=myTitle&repeat=123 as well. I ave come up with the following:
^post/(?!\d+($|/))(.+?($|/))(\d+$)?
Note: +? to use lazy quantifier, otherwise multiple slashes will be matched by .
and
^post/(?!\d+($|/))([^/\n\r]+($|/))(\d+$)?
Here I use [^/\n\r] instead of .+?
Patterns inside zero-width assertions like (?!\d++) are non-consuming, they do not "eat" chars, they only check the context while keeping the regex index at the same location as before matching the zero-width assertion pattern.
You can use any of the following:
^post/(?!\d+(?:/|$)).*
^post/(?!\d+(?=/|$)).*
^post/(?!\d+(?![^/])).*
See the regex demo. Details:
^post/ - start of input, post/ literal string
(?!\d+(?=/|$)) - a negative lookahead that fails the match if, immediately to the right of the current location, there are one or more digits followed with / or end of string
.* - the rest of the input.
Do not over complicate things when you can keep things simple by keeping 3 separate rewrite rules and since your query parameters are named differently you will need 3 separate rewrite rules anyway.
Consider:
Options -MultiViews
RewriteEngine On
RewriteRule ^post/(\d+) post.php?id=$1 [L,QSA,NC]
RewriteRule ^post/([^/]+)/(\d+) post.php?title=$1&repeat=$2 [L,QSA,NC]
RewriteRule ^post/([^/]*) post.php?title=$1 [L,QSA,NC]
Take note of Options -MultiViews. If this is not enabled in Apache config you must have it here otherwise it will keep all $_GET parameters empty in your php file.
Option MultiViews (see http://httpd.apache.org/docs/2.4/content-negotiation.html) is used by Apache's content negotiation module that runs before mod_rewrite and makes Apache server match extensions of files. So if /file is the URL then Apache will serve /file.html.
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.
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.
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".
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).