Reputation: 9392
I have a bunch of CSS containing image urls that I want to find/replace. The CSS often has more than one url per line, and the urls can vary pretty widely:
.class{display:inline;} .stuff{background:green url(/dir/subdir/dir.with.dots/image.png)} a{color:blue;} .more-stuff{background:url("../updir/newdir/file_image-new.jpg") no-repeat;}
I want to make each url into url(../images/<filename>.<ext>)
without the rest of the path.
The closest I have come is
/url\s*\("?(?:.+\/)*(.*?)\.(png|gif|jpe?g)"?\)/url(../images/$1.$2)/g
but the (?:.+\/)*
will select the CSS between image urls. If I add a ?
to the end of that section, I end up only replacing the first directory level.
Can I do this without look(ahead|behind)s? I don't know if the regex engine supports them.
Other examples I see seem to have the convenience of predictable line termination, with only one url per line.
Upvotes: 4
Views: 1357
Reputation: 9392
I used Toto's excellent answer to my question for a year.
However, the use case has expanded somewhat to include other images (.svg
), fonts (.eot
, .woff
), and people's CSS tricks (.eot#?iefix
). After a while, I got sick of adding extra file types to the regex.
The regex below (borrowing heavily from Toto) should take care of any file extension, even with junk on the end:
url\s*\("?\/?(?:[^\/]+\/)*?([^\/]+?\.[^\"\'\)\/]+)"?\)
url(../images/$1)
# If you want to exclude Base64 encoded data, put in a negative lookahead
url\s*\("?(?!data:)\/?(?:[^\/]+\/)*?([^\/]+?\.[^\"\'\)\/]+)"?\)
url(../images/$1)
# If your engine supports backreferences, you can match quotes
url\s*\(\*(['"]?)\/?(?:[^\/]+\/)*?([^\/]+?\.[^\/]+)\1\s*\)
url(../images/$2)
Upvotes: 2
Reputation: 91528
How about:
Find what: url\s*\("?/?(?:[^/]+/)*?([^/]+\.(?:png|gif|jpe?g))"?\)
Replace with: url(../images/$1)
Upvotes: 4