Why is my url rewriting rule not working properly? - nginx

I'm trying to write this redirection
images/catalog/1002/10002/main-200x250.12345.jpg to url images/catalog/1002/10002/main.jpg?w=200&h=250&vw=main
I tried this rule:
rewrite "^/images/(.*)/([a-z0-9]+)-([0-9])x([0-9]).([0-9]{5}).(jpg|jpeg|png|gif|ico)$" /images/$1/$2.$6?w=$3&h=$4&vw=$2 break;
It is not working, it return 404 not found error. I don't know what I'm missing.
Also when I remove double quotes (") I got this error
directive "rewrite" is not terminated by ";"
And I don't clear see the utility of the sign " and when should I use it or avoid it
I m working on a Mac with MAMP Pro v 5.2.2

You forgot to add a quantifier for the width and height numbers in your regex. Try this (I added a twice a +, you might want to use {X} instead, where X is the amount of digits for each number (if it is always the same amount of digits)):
rewrite "^/images/(.*)/([a-z0-9]+)-([0-9]+)x([0-9]+).([0-9]{5}).(jpg|jpeg|png|gif|ico)$" /images/$1/$2.$6?w=$3&h=$4&vw=$2 break;
Your reqular expression needs to be quoted because there is a } in it.
I think the nginx documentation about rewrite directive will answer your question, when a regular expression needs to be quoted:
If a regular expression includes the “}” or “;” characters, the whole
expressions should be enclosed in single or double quotes.

Related

Limitations on regex in nginx?

I had a rewrite rule on Apache for /year/month/date links in a form that specifically defined 4 digits, then 2 digits, then 2 digits, that looked like this:
^([0-9]{4})/([0-9]{2})/([0-9]{2})/$
On nginx this regex causes an error that says the whole line is not terminated by a ; sign, until i remove the {} brackets and leave the regex like this:
^/([0-9]+)/([0-9]+)/([0-9]+)/$
Is this limitation intentional on nginx's part or some mistake on my part?
The whole line from Apache:
RewriteRule ^([0-9]{4})/([0-9]{2})/([0-9]{2})/$ index.php?page=date&year=$1&month=$2&day=$3
The whole (working) line from nginx:
rewrite ^/([0-9]+)/([0-9]+)/([0-9]+)/$ /index.php?page=date&year=$1&month=$2&day=$3;
If a regular expression includes the “}” or “;” characters, the whole expressions should be enclosed in single or double quotes.
http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite

regex replace to match url() paths in css and replace with asset_path

I've been trying to follow this SO answer to try and write some regex to do a pattern replace with Grunt. My regex understanding is very basic so I'm pretty lost.
Matching
.selector {
background: url('../img/some.filename.png') no-repeat;
}
Output
.selector {
background: url(<%= asset_path 'some.filename.png' %>) no-repeat;
}
I understand something like /url\(.*?g'\)/ig will match the url() tag but I'm not sure how to isolate the filename from within that. Using the Grunt string-replace task to run the replace.
Any pointers?
I have conjured a beast of a regex that I believe does the job. It requires a positive lookbehind and a positive lookahead which I don't know if Grunt supports since I don't know what that is. I'm going to assume it does, otherwise I don't think it's possible without the lookaround.
I tested this regex using C#, so here it is!
Regex:
(?<=url\s*\('([\w\._-]+/)*)([\w\._-]+)(?='\))
Test String:
url ('fruit-veggie/apple_orange-pie/this.is-my_file.png')
I will break this down as it befuzzles even me. This is composed of 3 major parts.
Positive lookbehind:
(?<=url\s*\('([\w\._-]+/)*)
The (?<=) indicates whatever comes between the = and ) has to be part of the pattern that follows, but it will not be part of the match.
url\s*\(' will match url (' with or without spaces.
([\w\._-]+/)* will match any string that contains at least one word character, dot, underscore, or dash, followed by a forward slash. This will consume one folder path. The * at the end will make it consume any number of folders because you might not have a folder to begin with.
Actual file name:
([\w\._-]+)
This is identical to the folder pattern except without the forward slash at the end. This will match files without extensions.
Positive lookahead:
(?='\))
(?=) is the same as the positive lookbehind, except this is a lookahead which will check what comes after the pattern that precedes it.
'\) simply checks that the entire string is followed by a quote and a closing bracket.
For the folder/file name pattern, you will have to tweak it based on what characters would be valid in them. So if for whatever crazy reason they can contain a #, you will have to modify those portions of the regex to include that character.
Hopefully Grunt supports this regex, otherwise I will have wasted my time. But this was a fun challenge regardless!
Update
It seems JavaScript doesn't support lookbehinds. If what you're doing is specific to your current project only, why don't you try using two regex instead of one?
function GetFile (s) {
s = s.replace (/url\s*\('([\w\._-]+\/)*/g, '');
return s.match (/[\w\._-]+(?='\))/)[0];
}
var s = "url ('fruit-veggie/apple_orange-pie/this.is-my_file.png')";
console.log (GetFile (s));
This will erase everything up to but not including the first character of the file name. Then it returns the file name without the end quote and bracket, because JavaScript supports lookaheads.
You can use something like this :
(?:url\((.*?)\))
Demo
Explanation :
In javascript you can give :
var s="url('../img/some.filename.png')";
var ss= /(?:url\((.*?)\))/ ;
console.log(s.match(ss)[0]);

RegEx No Special characters

I am having allot of trouble finding a regex that will allow me to throw a error if the user tries to submit special characters especially "/" "\". I have a expression already that helps with other special characters but not the forward and backward slash Bonus: I don't want these ether but its not likely they will be entered. ~,!,#,#,$,%,^,&,*,().
I am currently using ^[\w{./\\(),'}+:?®©-]+$
The regex you have specifically allows / and \ (as well as ( and )). Change it like so:
^[\w{.,'}+:?®©-]+$
and keep removing any other characters you don't want to allow either.
In case you're wondering, the construct [...] is called a character class.
You can also use a negated character class like ^[^/\\()~!##$%^&*]*$ to allow any characters except /\()~!##$%^&*.

Rewriting a URL with RegEx

I have a RegEx problem. Consider the following URL:
http://ab.cdefgh.com/aa-BB/index.aspx
I need a regular expression that looks at "aa-BB" and, if it doesn't
match a number of specific values, say:
rr-GG
vv-VV
yy-YY
zz-ZZ
then the URL should redirect to some place. For example:
http://ab.cdefgh.com/notfound.aspx
In web.config I have urlrewrite rules. I need to know what
the regex would be between the tags.
<urlrewrites>
<rule>
<url>?</url>
<rewrite>http://ab.cdefgh.com/notfound.aspx</rewrite>
</rule>
</urlrewrites>
Assuming you don't care about the potential for the replacement pattern to be in the domain name or some other level of the directory structure, this should select on the pattern you're interested in:
http:\/\/ab\.cdefgh\.com\/(?:aa\-BB|rr\-GG|vv\-VV|yy\-YY|zz\-ZZ)\/index\.aspx
where the aa-BB, etc. patterns are simply "or"ed together using the | operator.
To further break this apart, all of the /, ., and - characters need to be escaped with a \ to prevent the regex from interpreting them as syntax. The (?: notation means to group the things being "or"ed without storing it in a backreference variable (this makes it more efficient if you don't care about retaining the value selected).
Here is a link to a demonstration (maybe this can help you play around with the regex here to get to exactly which character combinations you want)
http://rubular.com/r/UfB65UyYrj
Will this help?
^([a-z])\1-([A-Z])\2.*
It matches:
uu-FF/
aa-BB/
bb-CC/index
But not
aaBB
asdf
ba-BB
aA-BB
(Edit based on comment)
Just pipe delimit your desired urls inside of () and escaping special chars.
Eg.
^(xx-YY|yy-ZZ|aa-BB|goodStuff)/.*
But, I think you might actually want the following which matches anything other than the urls that you specify, so that all else goes to notfound.aspx:
^[^(xx-YY|yy-ZZ|aa-BB|goodStuff)]/.*
Assuming you want anything but xx-XX, yy-YY and zz-ZZ to redirect:
[^(xx\-XX)|(yy\-YY)|(zz\-ZZ)]

regular expression needed to rewrite URLs

I am trying to make a rewrite rule to check whether the URL ends with .htm or .html, but does not contain Archive.aspx.
The url starts out like
www.contoso.com/test.htm (or .html)
and ends up like
www.contoso.com/Archive.aspx?page=/test.htm
How can I do this with a regular expression?
You can use negative lookahead: (?!Archive\.aspx).*\.html?$

Resources