简体   繁体   English

在没有while循环条件的情况下执行组提取?

[英]Performing group extraction without while loop condition in javascript?

Scenario 情境

Extracting URLs from multiple CSS url() functional notation. 从多个CSS url()功能符号提取URL。 Given the following css value from project bootstrap : 从项目引导程序给出以下css值:

src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');

I need an array of URL strings like ["../fonts/glyphicons-halflings-regular.eot?#iefix", "../fonts/glyphicons-halflings-regular.woff2", ...] . 我需要一个URL字符串数组,例如["../fonts/glyphicons-halflings-regular.eot?#iefix", "../fonts/glyphicons-halflings-regular.woff2", ...]

Solution

Right now I use a while loop and regex matcher to extract URL strings from the parsed declaration via a CSS parser: 现在,我使用while循环和regex匹配器,通过CSS解析器从解析的声明中提取URL字符串:

var decValue = "url(foo), url(bar)";
// no data URI
var regexp = new RegExp(/url\(([^\(|^\)|^\"|^\']+)\)/g),
    matches = [],
    match;

while (match = regexp.exec(decValue), match !== null) {
    if (match[1].indexOf("data:") === -1) {
        matches.push(match[1]);
    }
}

// should print ["foo", "bar"]
console.log(matches);

Question

Is there a way to do this without using a while loop but keeping group matching? 有没有一种方法可以不使用while循环而保持组匹配呢?

To avoid a while loop you could move the grouping logic out in to a map function and use String.prototype.match to grab all matches globally: 为了避免while循环,您可以将分组逻辑移到map函数中,并使用String.prototype.match全局获取所有匹配项:

var decValue = "url(foo), url(bar)";

// no data URI
var urlExp = /url\([^)]+\)/g,
    uriExp = /\(["']?([^)]+)["']?\)/;

var matches = decValue.match(urlExp).map(function (url) {
    return uriExp.exec(url)[1];
});    

// should print ["foo", "bar"]
console.log(matches);

Unfortunately requires you to break up your regex, but it's more or less just group extraction via an iterator pattern. 不幸的是,您需要分解正则表达式,但这或多或少只是通过迭代器模式进行的组提取。

Because javascript doesn't support lookbehinds, you have to get creative when the text behind a position matters but you don't want to capture it. 由于javascript不支持向后搜索,因此当职位后面的文字很重要时,您就必须发挥创造力,但您不想捕获它。 This regex accounts for single and double quotation marks. 此正则表达式说明单引号和双引号。

Here's one method that uses replace to push to an array, it doesn't modify the original variable. 这是一种使用replace推入数组的方法,它不会修改原始变量。

 var css = "src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url(\\"../fonts/glyphicons-halflings-regular.woff\\") format('woff'), url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');" var garnerURLs = []; css.replace(/url\\(('[^']*'|"[^"]*"|[^\\)]*)\\)/g,function(match,p1) { if (p1.charAt(0) == "'" || p1.charAt(0) == "\\"") { garnerURLs.push(p1.substr(1,p1.length-2)) } else { garnerURLs.push(p1) } }); console.log(garnerURLs) console.log(css) 

url\(('[^']*'|"[^"]*"|[^\)]*)\)

Explanation: 说明:

 url                # Literal url
 \(                 # Literal (
 (                  # Opens CG1
     '              # Literal '
     [^']*          # Negated Character class (excludes the characters within)
     '              # Literal '
 |                  # Alternation (CG1)
     "              # Literal "
     [^"]*          # Negated Character class (excludes the characters within)
     "              # Literal "
 |                  # Alternation (CG1)
     [^\)]*         # Negated Character class (excludes the characters within)
 )                  # Closes CG1
 \)                 # Literal )

Any of the answers here, along with your current method, essentially involve a loop. 这里的任何答案以及您当前的方法,基本上都涉及一个循环。 Even if javascript supported lookbehinds, a simple match() method still loops over the list while it finds further matches. 即使javascript支持lookbehinds,一个简单的match()方法仍会在列表中循环查找更多匹配项。 In the end, any of these solutions is a fine solution. 最后,这些解决方案都是不错的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM