Come usare regex JavaScript su più righe?


275
var ss= "<pre>aaaa\nbbb\nccc</pre>ddd";
var arr= ss.match( /<pre.*?<\/pre>/gm );
alert(arr);     // null

Vorrei che il blocco PRE venisse raccolto, anche se si estende su personaggi newline. Pensavo che la bandiera "m" lo facesse. Non.

Ho trovato la risposta qui prima di pubblicare. Dato che pensavo di conoscere JavaScript (leggi tre libri, orario di lavoro) e non c'era una soluzione esistente in SO, oserei pubblicare comunque. lanciare pietre qui

Quindi la soluzione è:

var ss= "<pre>aaaa\nbbb\nccc</pre>ddd";
var arr= ss.match( /<pre[\s\S]*?<\/pre>/gm );
alert(arr);     // <pre>...</pre> :)

Qualcuno ha un modo meno enigmatico?

Modifica: questo è un duplicato ma poiché è più difficile da trovare del mio, non lo rimuovo.

Si propone [^]come un "punto multilinea". Quello che ancora non capisco è perché [.\n]non funziona. Immagino che questa sia una delle parti tristi di JavaScript ..


29
Una regex meno criptica? Impossibile, per natura.
Rubens Farias,

a proposito, dovresti leggere: "Parsing Html: The Cthulhu Way" codinghorror.com/blog/archives/001311.html
Rubens Farias

1
Il link è cambiato dal commento precedente: blog.codinghorror.com/parsing-html-the-cthulhu-way (5yrs-ish later)
dab

Risposte:


248

[.\n]non funziona perché .non ha un significato speciale dentro [], significa solo un letterale .. (.|\n)sarebbe un modo per specificare "qualsiasi carattere, inclusa una nuova riga". Se si desidera far corrispondere tutti i ritorni a capo, si avrebbe bisogno di aggiungere \rpure per includere Windows e classici fine riga stile Mac OS: (.|[\r\n]).

Questo risulta essere un po 'ingombrante, oltre che lento (vedi la risposta di KrisWebDev per i dettagli ), quindi un approccio migliore sarebbe quello di abbinare tutti i caratteri di spazi bianchi e tutti i caratteri non di spazi bianchi, con [\s\S], che corrisponderanno a tutto, ed è più veloce e più semplice.

In generale, non dovresti provare a usare un regexp per abbinare i tag HTML reali. Vedi, ad esempio, queste domande per ulteriori informazioni sul perché.

Invece, prova a cercare effettivamente il DOM per il tag di cui hai bisogno (usando jQuery lo rende più facile, ma puoi sempre fare document.getElementsByTagName("pre")con il DOM standard), quindi cerca il contenuto testuale di quei risultati con un regexp se devi abbinare il contenuto .


Quello che sto facendo è fare .wiki -> conversione HTML al volo, usando JavaScript. Pertanto, non ho ancora il DOM disponibile. Il file Wiki è principalmente la sua sintassi, ma consento l'uso di tag HTML se necessario. Il tuo consiglio è molto valido, se mi occupavo di DOM con questo. Grazie. :)
akauppi il

Giusto. Suppongo che questo sia un motivo valido per voler usare regex su HTML, sebbene le sintassi wiki mescolate con HTML possano avere tutti i tipi di casi angolari divertenti.
Brian Campbell,

2
[\r\n]applicato a una sequenza \ r \ n, corrisponderebbe prima a \ r e poi a \ n. Se vuoi abbinare l'intera sequenza in una sola volta, indipendentemente dal fatto che quella sequenza sia \ r \ n o solo \ n, usa il modello.|\r?\n
Eirik Birkeland,

1
Per abbinare un'intera stringa multilinea, prova l'avido [\s\S]+.
Boaz,

Voglio solo aggiungere ai posteri che la sintassi della regex JS ignorando il significato di .inside []è diversa rispetto ad altri framework regex, in particolare quello avanzato in .NET. Gente, per favore, non date per scontato che le regex siano multipiattaforma, spesso no !!
Sig. TA,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.