2

まず、「 HTML を 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&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));

発生する価格分岐ごとに最初の価格分岐に 1 回一致します (つまり、 があり、name=13回一致する場合。name=5name=15name=1

どこで間違っていますか?

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 の 3 つのブロックを 1 つの 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/

これにより、HTML で (やや脆弱な) 正規表現を使用するのではなく、これらの要素のすべての DOM トラバーサル関数を使用できます。

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

正規表現を1回実行し、最初の一致のみを返します(()sのために、最初の一致の3つのコピーを返すのを間違えました)。それらをループすることにより、すべての一致が使い果たされるまで正規表現を評価し続けます。PHP のpreg_match.

于 2012-02-20T07:13:54.147 に答える