我需要url()
从 CSS 文件中获取所有 URL(表达式)。例如:
b { background: url(img0) }
b { background: url("img1") }
b { background: url('img2') }
b { background: url( img3 ) }
b { background: url( "img4" ) }
b { background: url( 'img5' ) }
b { background: url (img6) }
b { background: url ("img7") }
b { background: url ('img8') }
{ background: url('noimg0) }
{ background: url(noimg1') }
/*b { background: url(noimg2) }*/
b { color: url(noimg3) }
b { content: 'url(noimg4)' }
@media screen and (max-width: 1280px) { b { background: url(img9) } }
b { background: url(img10) }
我需要获取所有img*
URL,但不是noimg*
URL(无效语法或无效属性或内部注释)。
我尝试过使用好的旧正则表达式。经过一些试验和错误,我得到了这个:
private static IEnumerable<string> ParseUrlsRegex (string source)
{
var reUrls = new Regex(@"(?nx)
url \s* \( \s*
(
(?! ['""] )
(?<Url> [^\)]+ )
(?<! ['""] )
|
(?<Quote> ['""] )
(?<Url> .+? )
\k<Quote>
)
\s* \)");
return reUrls.Matches(source)
.Cast<Match>()
.Select(match => match.Groups["Url"].Value);
}
这是一个疯狂的正则表达式,但它仍然不起作用——它匹配 3 个无效 URL(即 2、3 和 4)。再者,大家会说用正则来解析复杂的语法是错误的。
让我们尝试另一种方法。根据这个问题,唯一可行的选择是ExCSS(其他的要么太简单,要么已经过时)。使用 ExCSS 我得到了这个:
private static IEnumerable<string> ParseUrlsExCss (string source)
{
var parser = new StylesheetParser();
parser.Parse(source);
return parser.Stylesheet.RuleSets
.SelectMany(i => i.Declarations)
.SelectMany(i => i.Expression.Terms)
.Where(i => i.Type == TermType.Url)
.Select(i => i.Value);
}
与正则表达式解决方案不同,此解决方案不会列出无效的 URL。但它没有列出一些有效的!即 9 和 10。看起来这是一些 CSS 语法的已知问题,如果不从头开始重写整个库,就无法修复它。ANTLR rewrite 似乎被放弃了。
问题:如何从 CSS 文件中提取所有 URL?(我需要解析任何CSS 文件,而不仅仅是上面作为示例提供的那个。请不要为“noimg”或假设单行声明。)
注意这不是“工具推荐”问题,因为任何解决方案都可以,无论是一段代码、对上述解决方案之一的修复、库或其他任何东西;我已经明确定义了我需要的功能。