4

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.

6
  • Parsing CSS with regex is a pain. Anyways, what language/tool are you using ? Commented Jan 30, 2014 at 15:02
  • I've been testing with Notepad++ and reFiddle (for the highlighting), but will ultimately use sed or python. Commented Jan 30, 2014 at 15:06
  • I will try to do this in Python but I've got one more question: Does the extensions need to be matched dynamically or will you define them with say (?:png|jpe?g|gif|custom\.extension) ? Commented Jan 30, 2014 at 15:14
  • @HamZa: I looked at the SO link. Yikes! I have done things like this (where finding url([^)]+) is easy, finding url(<magic>) is hard) in C# using delegates, but that's not an option here. I can define the extensions. No need to find them. Commented Jan 30, 2014 at 15:16
  • 1
    I've got something to do, I will maybe come back later but meanwhile enjoy this regex Commented Jan 30, 2014 at 15:21

2 Answers 2

4

How about:

Find what: url\s*\("?/?(?:[^/]+/)*?([^/]+\.(?:png|gif|jpe?g))"?\)
Replace with: url(../images/$1)

Sign up to request clarification or add additional context in comments.

Comments

2

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)

Bonus

# 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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.