var ss= "<pre>aaaa\nbbb\nccc</pre>ddd";
var arr= ss.match( /<pre.*?<\/pre>/gm );
alert(arr); // null
Eu gostaria que o bloco PRE fosse escolhido, mesmo que se estendesse por caracteres de nova linha. Eu pensei que a bandeira 'm' faz isso. Não.
Encontre a resposta aqui antes de postar. Desde que achei que sabia JavaScript (li três livros, trabalhei horas) e não havia uma solução existente na SO, ousarei postar de qualquer maneira. jogue pedras aqui
Então a solução é:
var ss= "<pre>aaaa\nbbb\nccc</pre>ddd";
var arr= ss.match( /<pre[\s\S]*?<\/pre>/gm );
alert(arr); // <pre>...</pre> :)
Alguém tem uma maneira menos enigmática?
Edit: esta é uma duplicata, mas como é mais difícil de encontrar que a minha, não a removo.
Ele propõe [^]
como um "ponto multilinha". O que ainda não entendo é por [.\n]
que não funciona. Acho que essa é uma das partes tristes do JavaScript.
javascript
regex
akauppi
fonte
fonte
Respostas:
[.\n]
não funciona porque.
não tem um significado especial dentro[]
, significa apenas um literal.
.(.|\n)
seria uma maneira de especificar "qualquer caractere, incluindo uma nova linha". Se você quiser combinar todas as novas linhas, você precisa adicionar\r
, assim como para incluir o Windows e clássicos finais de linha estilo Mac OS:(.|[\r\n])
.Isso acaba sendo um tanto complicado e lento (consulte a resposta de KrisWebDev para obter detalhes ); portanto, uma abordagem melhor seria combinar todos os caracteres de espaço em branco e todos os caracteres que não sejam de espaço em branco com
[\s\S]
, o que corresponderá a tudo e é mais rápido e rápido. mais simples.Em geral, você não deve tentar usar uma regexp para corresponder às tags HTML reais. Veja, por exemplo, estas perguntas para obter mais informações sobre o porquê.
Em vez disso, tente realmente pesquisar no DOM a tag que você precisa (o uso do jQuery facilita isso, mas você sempre pode fazer
document.getElementsByTagName("pre")
com o DOM padrão) e, em seguida, pesquise o conteúdo de texto desses resultados com uma expressão regular se precisar corresponder ao conteúdo .fonte
[\r\n]
aplicado a uma sequência \ r \ n, corresponderia primeiro a \ re depois \ n. Se você deseja corresponder a seqüência inteira de uma vez, independentemente de essa sequência está \ r \ n ou apenas \ n, use o padrão.|\r?\n
[\s\S]+
..
dentro,[]
é diferente de outras estruturas regex, principalmente a avançada no .NET. Gente, por favor, não assuma que as expressões regulares são multiplataforma, elas frequentemente não são !!NÃO use em
(.|[\r\n])
vez de.
para correspondência de várias linhas.Use em
[\s\S]
vez de.
para correspondência multilinhaAlém disso, evite a ganância onde não for necessário usando
*?
ou+?
quantificador em vez de*
ou+
. Isso pode ter um enorme impacto no desempenho.Veja a referência que eu fiz: http://jsperf.com/javascript-multiline-regexp-workarounds
NB: Você também pode usar,
[^]
mas está obsoleto no comentário abaixo.fonte
[^]
qualquer maneira. Por um lado, o JavaScript é o único sabor que conheço que suporta esse idioma e, mesmo lá, ele é usado nem de longe com a mesma frequência[\s\S]
. Por outro lado, a maioria dos outros sabores permite escapar do]
listando-o primeiro. Em outras palavras, em JavaScript[^][^]
combina quaisquer dois caracteres, mas em .NET que corresponde a qualquer um outro personagem que]
,[
ou^
.\S
irá corresponder\r
ou\n
contra algum outro personagem?[\s\S]
a outros, como[\d\D]
ou[\w\W]
?/<p>Can[^]*?<\/p>/
não corresponde ao mesmo conteúdo que/<p>Can[^]*<\/p>/
. A variante gananciosa deve ser alterada/<p>(?:[^<]|<(?!\/p>))*<\/p>/
para corresponder ao mesmo conteúdo.Você não especifica o seu ambiente e a versão do Javascript (ECMAscript), e eu sei que este post foi de 2009, mas, para completar, com o lançamento do ECMA2018, agora podemos usar o
s
sinalizador para fazer.
corresponder '\ n', consulte https : //stackoverflow.com/a/36006948/141801Portanto:
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 estou usando-o em um teste de Typecript que estou escrevendo e, presumivelmente, se tornará mais popular com o passar do tempo.
fonte
[.\n]
não funciona, porque ponto[]
(por definição de regex; não apenas javascript) significa o caractere de ponto. Você pode usar(.|\n)
(ou(.|[\n\r])
) em vez disso.fonte
[\s\S]
é o idioma JavaScript mais comum para corresponder a tudo, incluindo novas linhas. É mais fácil para os olhos e muito mais eficiente do que uma abordagem baseada em alternância(.|\n)
. (É, literalmente, significa "qualquer caractere que é espaço em branco ou qualquer caractere que não seja espaço em branco.).
e\n
, e por[.\n]
que não funciona. Como mencionado na pergunta,[^]
também é uma boa abordagem.Eu testei (Chrome) e funcionou para mim (ambos
[^]
e[^\0]
), alterando o ponto (.
) por um[^\0]
ou outro[^]
, porque o ponto não corresponde à quebra de linha (veja aqui:http://www.regular-expressions.info/dot.html ).fonte
[^\0]
é que ele não corresponderá a caracteres nulos, mesmo que caracteres nulos sejam permitidos em strings Javascript (consulte esta resposta ).Além dos exemplos acima mencionados, é uma alternativa.
Onde
\w
é para palavras e\s
é para espaços em brancofonte