首先,请勿链接到“Don't parse HTML with Regex”帖子:)
我有以下HTML,用于显示各种货币,公司和税前价格:
<span id="price_break_12345" name="1">
<span class="price">
<span class="inc" >
<span class="GBP">£25.00</span>
<span class="USD" style="display:none;">$34.31</span>
<span class="EUR" style="display:none;">27.92 €</span>
</span>
<span class="ex" style="display:none;">
<span class="GBP">£20.83</span>
<span class="USD" style="display:none;">$34.31</span>
<span class="EUR" style="display:none;">23.27 €</span>
</span>
</span>
<span style="display:none" class="raw_price">25.000</span>
</span>
AJAX调用返回单个HTML字符串,其中包含上述HTML的多个副本,价格各不相同。我想与正则表达式匹配的是:
name
span
属性的值
到目前为止我所拥有的是:
var price_regex = new RegExp(/(<span([\s\S]*?)><span([\s\S]*?)>([\s\S]*?)<\/span><\/span\>)/gm);
console && console.log(price_regex.exec(product_price));
对于每次发生的价格中断,它都会匹配第一次价格中断(因此,如果name=1
,name=5
和name=15
匹配name=1
3次。
我出错的行踪?
答案 0 :(得分:2)
所以,如果你可以指望每个块中第一个跨度的格式,如下所示:
<span id="price_break_12345" name="1">
然后,你如何使用这样的代码循环所有匹配。此代码标识第一个范围中的price_break_xxxx id值,然后选择以下name属性:
var re = /id="price_break_\d+"\s+name="([^"]+)"/gm;
var match;
while (match = re.exec(str)) {
console.log(match[1]);
}
你可以在这里看到它:http://jsfiddle.net/jfriend00/G39ne/。
我使用转换器将三个HTML块放入一个javascript字符串中(以模拟从ajax调用中返回的内容),以便我可以在其上运行代码。
更有效的方法是使用浏览器的HTML解析器为您完成所有工作。假设你有一个名为`str'的字符串变量中的HTML,你可以像这样使用浏览器的解析器:
function getElementChildren(parent) {
var elements = [];
var children = parent.childNodes;
for (var i = 0, len = children.length; i < len; i++) {
// collect element nodes only
if (children[i].nodeType == 1) {
elements.push(children[i]);
}
}
return(elements);
}
var div = document.createElement("div");
div.innerHTML = str;
var priceBlocks = getElementChildren(div);
for (i = 0; i < priceBlocks.length; i++) {
console.log(priceBlocks[i].id + ", " + priceBlocks[i].getAttribute("name") + "<br>");
}
在这里演示:http://jsfiddle.net/jfriend00/F6D8d/
这将为您提供这些元素的所有DOM遍历函数,而不是在HTML上使用(有些脆弱的)正则表达式。
答案 1 :(得分:0)
在很大程度上感谢jfriend让我意识到为什么我的正则表达式以一种奇怪的方式匹配(while (price_break = regex.exec(string))
而不是只执行一次),我已经有了它的工作:
var price_regex = new RegExp(/<span[\s\S]*?name="([0-9]+)"[\s\S]*?><span[\s\S]*?>[\s\S]*?<\/span><\/span\>/gm);
var price_break;
while (price_break = price_regex.exec(strProductPrice))
{
console && console.log(price_break);
}
我有大量无用的()
只是堵塞了结果集,所以剥离它们会让事情变得简单得多。
另一件事,如上所述,最初我只是在做
price_break = price_regex.exec(strProductPrice)
运行正则表达式一次,并仅返回第一个匹配(由于()
s,我误认为返回了第一个匹配的3个副本)。通过循环遍历它们,它会继续评估正则表达式,直到所有匹配都已用完为止,我认为它正常运行,类似于PHP的preg_match
。