var ss= "<pre>aaaa\nbbb\nccc</pre>ddd";
var arr= ss.match( /<pre.*?<\/pre>/gm );
alert(arr); // null
Je voudrais que le bloc PRE soit récupéré, même s'il s'étend sur des caractères de nouvelle ligne. Je pensais que le drapeau «m» le faisait. Ne fait pas.
J'ai trouvé la réponse ici avant de poster. Depuis que je pensais connaître JavaScript (lire trois livres, travailler des heures) et qu'il n'y avait pas de solution existante chez SO, j'oserais poster quand même. jeter des pierres ici
La solution est donc:
var ss= "<pre>aaaa\nbbb\nccc</pre>ddd";
var arr= ss.match( /<pre[\s\S]*?<\/pre>/gm );
alert(arr); // <pre>...</pre> :)
Quelqu'un a-t-il un moyen moins cryptique?
Edit: c'est un double mais comme il est plus difficile à trouver que la mienne, je ne supprime pas.
Il propose [^]
un "point multiligne". Ce que je ne comprends toujours pas, c'est pourquoi [.\n]
ça ne marche pas. Je suppose que c'est l'une des tristes parties de JavaScript ..
javascript
regex
akauppi
la source
la source
Réponses:
[.\n]
ne fonctionne pas car.
n'a pas de signification particulière à l'intérieur de[]
, cela signifie simplement un littéral.
.(.|\n)
serait un moyen de spécifier "n'importe quel caractère, y compris une nouvelle ligne". Si vous voulez faire correspondre tous les sauts de ligne, vous devez ajouter\r
ainsi d'inclure Windows et classiques de fin de ligne de style Mac OS:(.|[\r\n])
.Cela s'avère être un peu lourd, mais aussi lent (voir la réponse de KrisWebDev pour plus de détails ), donc une meilleure approche serait de faire correspondre tous les caractères blancs et tous les caractères non blancs, avec
[\s\S]
, qui correspondra à tout, et est plus rapide et plus simple.En général, vous ne devriez pas essayer d'utiliser une expression rationnelle pour faire correspondre les balises HTML réelles. Voir, par exemple, ces questions pour plus d'informations sur pourquoi.
Au lieu de cela, essayez de rechercher dans le DOM la balise dont vous avez besoin (l'utilisation de jQuery rend cela plus facile, mais vous pouvez toujours le faire
document.getElementsByTagName("pre")
avec le DOM standard), puis recherchez le contenu textuel de ces résultats avec une expression régulière si vous devez faire une correspondance avec le contenu .la source
[\r\n]
appliqué à une séquence \ r \ n, correspondrait d'abord à \ r puis à \ n. Si vous souhaitez faire correspondre la séquence entière à la fois, que cette séquence soit \ r \ n ou juste \ n, utilisez le modèle.|\r?\n
[\s\S]+
..
inside[]
est différente de celle des autres frameworks regex, en particulier celui avancé de .NET. Les gens, s'il vous plaît, ne supposez pas que les regex sont multiplates-formes, ce n'est souvent pas le cas !!NE PAS utiliser
(.|[\r\n])
au lieu de.
pour l'appariement multiligne.A UTILISER
[\s\S]
au lieu de.
pour l'appariement multiligneÉvitez également la gourmandise là où elle n'est pas nécessaire en utilisant
*?
ou+?
quantifier au lieu de*
ou+
. Cela peut avoir un impact énorme sur les performances.Voir le benchmark que j'ai fait: http://jsperf.com/javascript-multiline-regexp-workarounds
NB: Vous pouvez également utiliser
[^]
mais il est déconseillé dans le commentaire ci-dessous.la source
[^]
toute façon l' utilisation . D'une part, JavaScript est la seule saveur que je connaisse qui prend en charge cet idiome, et même là, il est utilisé aussi loin que souvent[\s\S]
. D'un autre côté, la plupart des autres saveurs vous permettent de vous échapper en les]
répertoriant d'abord. En d' autres termes, en JavaScript[^][^]
correspond à tous les deux personnages, mais dans .NET il correspond à un caractère autre que]
,[
ou^
.\S
cela correspondra\r
ou\n
par rapport à un autre personnage?[\s\S]
les autres, comme[\d\D]
ou[\w\W]
?/<p>Can[^]*?<\/p>/
ne correspond pas au même contenu que/<p>Can[^]*<\/p>/
. La variante gourmande doit être modifiée/<p>(?:[^<]|<(?!\/p>))*<\/p>/
pour correspondre au même contenu.Vous ne spécifiez pas votre environnement et votre version de Javascript (ECMAscript), et je me rends compte que ce post date de 2009, mais juste pour être complet, avec la sortie d'ECMA2018, nous pouvons maintenant utiliser le
s
drapeau pour faire.
correspondre '\ n', voir https : //stackoverflow.com/a/36006948/141801Donc:
Ceci est un ajout récent et ne fonctionnera pas dans de nombreux environnements actuels, par exemple Node v8.7.0 ne semble pas le reconnaître, mais il fonctionne dans Chromium, et je l'utilise dans un test Typescript que j'écris et probablement deviendra plus grand public au fil du temps.
la source
[.\n]
ne fonctionne pas, car dot in[]
(par définition regex; pas seulement javascript) signifie le caractère point. Vous pouvez utiliser(.|\n)
(ou(.|[\n\r])
) à la place.la source
[\s\S]
est l'idiome JavaScript le plus courant pour tout faire correspondre, y compris les sauts de ligne. C'est plus agréable pour les yeux et beaucoup plus efficace qu'une approche basée sur l'alternance comme(.|\n)
. (Cela signifie littéralement «tout personnage qui est un espace ou tout caractère qui n'est pas un espace.).
et\n
, et pourquoi[.\n]
ne fonctionne pas. Comme mentionné dans la question,[^]
c'est aussi une bonne approche.Je l'ai testé (Chrome) et cela fonctionne pour moi (à la fois
[^]
et[^\0]
), en changeant le point (.
) par[^\0]
ou[^]
, car le point ne correspond pas au saut de ligne (voir ici:http://www.regular-expressions.info/dot.html ).la source
[^\0]
est qu'il ne correspondra pas aux caractères nuls même si les caractères nuls sont autorisés dans les chaînes Javascript (voir cette réponse ).En plus des exemples ci-dessus, il s'agit d'une alternative.
Où
\w
est pour les mots et\s
pour les espaces blancsla source