2

首先,不要链接到“不要使用正则表达式解析 HTML ”帖子 :)

我有以下 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&nbsp;€&lt;/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&nbsp;€&lt;/span>
        </span>
    </span>
    <span style="display:none" class="raw_price">25.000</span>
</span>

AJAX 调用返回一个 HTML 字符串,其中包含上述 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=13 次。

我哪里错了?

4

2 回答 2

2

因此,如果您可以像这样依靠每个块中第一个跨度的格式:

<span id="price_break_12345" name="1">

然后,您如何使用这样的代码循环遍历所有匹配项。此代码识别第一个跨度中的 price_break_xxxx id 值,然后选择以下名称属性:

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 上使用(有点脆弱的)正则表达式。

于 2012-02-20T07:03:00.020 回答
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.

于 2012-02-20T07:13:54.147 回答