Domanda

Prima di tutto, non collegare al "Non analizzare HTML con Regex" inviare :)

Ho il seguente HTML, che viene utilizzato per visualizzare i prezzi in varie valute, INC ed ex tasse:

<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;€</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;€</span>
        </span>
    </span>
    <span style="display:none" class="raw_price">25.000</span>
</span>

Una chiamata AJAX restituisce una singola stringa di HTML, contenente più copie dell'HTML sopra, con i prezzi che variano. Quello che sto cercando di abbinare con Regex è:

  • Ogni blocco dell'HTML sopra (come menzionato, si verifica più volte nella stringa di ritorno)
  • Il valore del name attributo più esterno span

Quello che ho finora è questo:

var price_regex = new RegExp(/(<span([\s\S]*?)><span([\s\S]*?)>([\s\S]*?)<\/span><\/span\>)/gm);
console && console.log(price_regex.exec(product_price));

Corrisponde alla prima pausa di prezzo una volta per ogni interruzione del prezzo che si verifica (quindi se c'è name=1, name=5 e name=15 corrisponde name=1 3 volte.

Dove sto andando storto?

È stato utile?

Soluzione 2

Grazie in gran parte a Jfriend per avermi fatto capire perché il mio regex si abbinava in modo strano (while (price_break = regex.exec(string)) Invece di farlo solo una volta), ho funzionato:

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);
}

Avevo un sacco di inutili () Che stavano solo intasando il set di risultati, quindi spogliarle ha reso le cose molto più semplici.

L'altra cosa, come menzionato sopra era che originariamente stavo solo facendo

price_break = price_regex.exec(strProductPrice)

che esegue una volta il regex e restituisce solo la prima partita (che ho scambiato per aver restituito 3 copie della prima partita, a causa del ()S). Loop su di loro, continua a valutare il regex fino a quando tutte le partite non sono state esaurite, cosa che ho supposto che normalmente lo facesse, simile a quella di PHP preg_match.

Altri suggerimenti

Quindi, se puoi contare sul formato di quel primo intervallo in ogni blocco come questo:

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

Quindi, che ne dici di usare codice come questo per scorrere tutte le partite. Questo codice identifica il valore ID Price_break_xxxx in quel primo intervallo e quindi raccoglie il seguente attributo nome:

var re = /id="price_break_\d+"\s+name="([^"]+)"/gm;
var match;
while (match = re.exec(str)) {
    console.log(match[1]);
}

Puoi vederlo funzionare qui: http://jsfiddle.net/jfriend00/g39ne/.

Ho usato un convertitore per trasformare tre dei tuoi blocchi di HTML in una singola stringa JavaScript (per simulare ciò che ricevi dalla tua chiamata Ajax) in modo da poter eseguire il codice su di esso.


Un modo più robusto per farlo è solo usare il parser HTML del browser per fare tutto il lavoro per te. Supponendo che tu abbia l'HTML in una variabile di stringa denominata `STR ', puoi usare il parser del browser in questo modo:

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>");
}

Demo qui: http://jsfiddle.net/jfriend00/f6d8d/

Questo ti lascerà con tutte le funzioni di attraversamento DOM per questi elementi piuttosto che utilizzare le espressioni regolari (un po 'fragili) su HTML.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top