Reputation: 578
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?
Upvotes: 2
Views: 2046
Reputation: 3230
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\._-]+/)*)
(?<=)
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.
Upvotes: 1