Como usar o JavaScript regex em várias linhas?

var ss= "
aaaa\nbbb\nccc

ddd"; var arr= ss.match( /<pre.*?/gm ); alert(arr); // null

Eu quero que o bloco PRE seja pego, mesmo que se estenda por caracteres de nova linha. Eu pensei que a bandeira ‘m’ faz isso. Não.

Encontrei a resposta aqui antes de postar. Desde que eu pensei que sabia JavaScript (leia três livros, trabalhei horas) e não havia uma solução existente no SO, ousarei postar de qualquer maneira. jogue pedras aqui

Então a solução é:

 var ss= "
aaaa\nbbb\nccc

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

...

🙂

Alguém tem uma maneira menos enigmática?

Edit: esta é uma duplicata, mas desde que é mais difícil de encontrar do que o meu, eu não removo.

Propõe [^] como um “ponto multilinha”. O que eu ainda não entendo é porque [.\n] não funciona. Acho que esta é uma das partes tristes do JavaScript ..

[.\n] não funciona porque . não tem significado especial dentro de [] , significa apenas um literal . . (.|\n) seria uma maneira de especificar “qualquer caractere, incluindo uma nova linha”. Se você quiser corresponder a todas as novas linhas, você precisará adicionar também para include o Windows e terminações de linha clássicas do estilo Mac OS: (.|[\r\n]) .

Isso acaba sendo um tanto complicado, assim como lento, (veja a resposta do KrisWebDev para detalhes ), então uma abordagem melhor seria combinar todos os caracteres em branco e todos os caracteres que não são espaços em branco, com [\s\S] , tudo, e é mais rápido e mais simples.

Em geral, você não deve tentar usar um regexp para corresponder às tags HTML reais. Veja, por exemplo, estas perguntas para mais informações sobre o porquê.

Em vez disso, tente realmente pesquisar o DOM para a tag que você precisa (usando jQuery torna isso mais fácil, mas você sempre pode document.getElementsByTagName("pre") com o DOM padrão) e, em seguida, pesquisar o conteúdo de texto desses resultados com um regexp se você precisa combinar contra o conteúdo.

NÃO use (.|[\r\n]) vez de . para correspondência multilinha.

NÃO use [\s\S] vez de . para correspondência multilinha

Além disso, evite ganância quando não for necessário usando *? ou +? quantificador em vez de * ou + . Isso pode ter um impacto enorme no desempenho.

Veja o benchmark que fiz: http://jsperf.com/javascript-multiline-regexp-workarounds

 Using [^]: fastest Using [\s\S]: 0.83% slower Using (.|\r|\n): 96% slower Using (.|[\r\n]): 96% slower 

NB: Você também pode usar [^] mas está obsoleto no comentário abaixo.

[.\n] não funciona, porque ponto em [] (por definição regex; não apenas javascript) significa o caractere de ponto. Você pode usar (.|\n) (ou (.|[\n\r]) ).

Eu testei (Chrome) e funciona para mim (ambos [^] e [^\0] ), alterando o ponto ( . ) Por [^\0] ou [^] , porque o ponto não corresponde quebra de linha (veja aqui: http://www.regular-expressions.info/dot.html ).

 var ss= "
aaaa\nbbb\nccc

ddd"; var arr= ss.match( /

/gm ); alert(arr); //Working

Você não especifica o seu ambiente e versão do Javascript (ECMAscript), e percebo que este post foi de 2009, mas apenas para completar, com o lançamento do ECMA2018, podemos agora usar o sinalizador s para causar . para corresponder a “\ n”, consulte https://stackoverflow.com/a/36006948/141801

Portanto:

 let s = 'I am a string\nover several\nlines.'; console.log('String: "' + s + '".'); let r = /string.*several.*lines/s; // Note 's' modifier console.log('Match? ' + r.test(s); // 'test' returns true 

Esta é uma adição recente e não funcionará em muitos ambientes atuais, por exemplo, o Nó v8.7.0 parece não reconhecê-lo, mas funciona no Chromium, e eu estou usando em um teste do tipo Typescript que estou escrevendo e presumivelmente vai se tornar mais mainstream com o passar do tempo.

Além dos exemplos acima mencionados, é um suplente.

 ^[\\w\\s]*$ 

Onde \w é para palavras e \s é para espaços em branco