Birden fazla satırda JavaScript normal ifadesi nasıl kullanılır?


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

Yeni satır karakterlerine yayılmış olsa da, PRE bloğunun kaldırılmasını istiyorum. 'M' bayrağının bunu yaptığını düşündüm. Değil.

Göndermeden önce cevabı burada buldum. SCECE JavaScript'i bildiğimi düşündüm (üç kitap okudum, çalışma saatleri) ve SO'da mevcut bir çözüm yoktu, yine de yayınlamaya cesaret edeceğim. buraya taş at

Yani çözüm:

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

Herkesin daha az şifreli bir yolu var mı?

Düzenleme: Bu bir kopya ama benimkinden bulmak daha zor olduğundan, kaldırmam.

[^]Bir "çok satırlı nokta" olarak öneriyor . Hala anlamadığım şey neden [.\n]işe yaramıyor. Sanırım bu JavaScript'in üzücü kısımlarından biri ..


29
Daha az şifreli bir regex? Doğası gereği imkansız.
Rubens Farias

btw, şunu okumalısınız: "Html Ayrıştırma: Cthulhu Yolu" codinghorror.com/blog/archives/001311.html
Rubens Farias

1
Bağlantı önceki yorumdan değişti: blog.codinghorror.com/parsing-html-the-cthulhu-way ( 5yrs -ish sonra)
dab

Yanıtlar:


248

[.\n]işe yaramaz çünkü .içinde özel bir anlamı yoktur [], sadece bir anlam anlamına gelir .. (.|\n)"yeni satır dahil herhangi bir karakteri" belirtmenin bir yolu olabilir. Tüm yeni satır eşleştirmek istiyorsanız, eklemek gerekir \rWindows ve klasik Mac OS tarzı satır sonları dahil etmek de: (.|[\r\n]).

Bu biraz hantal ve yavaş olduğu ortaya çıkıyor ( ayrıntılar için KrisWebDev'in cevabına bakın ), bu nedenle tüm beyaz karakterleri ve tüm beyaz olmayan karakterleri, [\s\S]her şeyi eşleştirecek ve daha hızlı ve daha basit.

Genel olarak, gerçek HTML etiketleriyle eşleşmesi için bir normal ifade kullanmaya çalışmamalısınız. Örneğin, nedeniyle ilgili daha fazla bilgi için bu sorulara bakın.

Bunun yerine, DOM'da ihtiyacınız olan etiketi aramayı deneyin (jQuery kullanmak bunu kolaylaştırır, ancak her zaman document.getElementsByTagName("pre")standart DOM ile yapabilirsiniz ) ve ardından içeriklerle eşleşmeniz gerekiyorsa bu sonuçların metin içeriğinde normal ifadeyle arama yapın .


Yaptığım şey JavaScript kullanarak .wiki -> HTML dönüşümünü anında yapmak. Bu nedenle, henüz DOM'um yok. Wiki dosyası çoğunlukla kendi sözdizimidir, ancak gerekirse HTML etiketlerinin kullanılmasına izin veririm. Bu konuda DOM ile uğraşıyorsam, tavsiyeniz çok geçerli. Teşekkürler. :)
akauppi

Yeterince adil. HTML ile regexes kullanmak istemek için geçerli bir neden olduğunu, ancak HTML ile karıştırılan wiki sözdizimleri eğlenceli köşe durumlarda her türlü olabilir sanırım.
Brian Campbell

2
[\r\n]\ r \ n dizisine uygulandığında, önce \ r ve sonra \ n ile eşleşir. Eğer desen kullanın n \ bakılmaksızın bu dizi olup olmadığı \ r seferde tüm diziyi eşleştirmek ya da sadece \ n isterseniz.|\r?\n
Eirik Birkeland

1
Çok satırlı bir dizenin tamamını eşleştirmek için açgözlü olanı deneyin [\s\S]+.
Boaz

Sadece anlamını görmezden JS regex sözdizimi ondan kuşaklar için eklemek istediğiniz .içeride []olan farklı diğer regex çerçeveler, .NET özellikle gelişmiş olandan. İnsanlar, regexes çapraz platform olduğunu varsayalım, sık sık değil !!
Bay TA

330

Çok satırlı eşleştirme (.|[\r\n])yerine KULLANMAYIN ..

Çok satırlı eşleştirme [\s\S]yerine DO kullanın.

Ayrıca kullanarak gerekli değildir önlemek açgözlülük *?ya +?yerine miktar belirleyici *ya +. Bunun büyük bir performans etkisi olabilir.

Yaptığım karşılaştırmaya bakın: 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

Not: Ayrıca kullanabilirsiniz, [^]ancak aşağıdaki yorumda kullanımdan kaldırılmıştır.


22
İyi puan, ama [^]yine de kullanmaya karşı öneririz . Bir yandan, JavaScript, bu deyimi destekleyen bildiğim tek lezzet ve hatta orada hiçbir yerde olduğu kadar sık ​​kullanılmıyor [\s\S]. Öte yandan, çoğu diğer lezzetler ]önce listeleyerek kaçmanıza izin verir . Diğer bir deyişle, JavaScript [^][^]herhangi iki karakter ile eşleşir, ancak .NET herhangi maçları biri dışında karakter başka ], [ya ^.
Alan Moore

1
\SBunun başka bir karakterle eşleşeceğini \rveya bir \nkarakterle eşleşeceğini nereden biliyorsunuz ?
Gili

3
Bkz bu soruyu \ s \ S detaylar için. Bu, tüm boşluk karakterleriyle + boşluk olmayan tüm karakterlerle = tüm karakterlerle eşleşecek bir hack'tir. Normal ifade özel karakter belgeleri için ayrıca MDN'ye bakın .
KrisWebDev

4
[\s\S]Başkaları tercih etmek için herhangi bir sebep , [\d\D]veya [\w\W]?
Phrogz

1
Açgözlü operatör için yaptığınız testin hileli olduğunu hızlı bir şekilde belirteyim. /<p>Can[^]*?<\/p>/ile aynı içeriğe uymuyor /<p>Can[^]*<\/p>/. Açgözlü varyant /<p>(?:[^<]|<(?!\/p>))*<\/p>/aynı içeriğe uyacak şekilde değiştirilmelidir .
3limin4t0r

19

Ortamınızı ve Javascript'in (ECMAscript) sürümünü belirtmezsiniz ve bu yayının 2009'dan geldiğini anlıyorum, ancak tamlık için, ECMA2018'in yayınlanmasıyla artık '\ n' ile eşleşmek için sbayrağı kullanabiliriz, https'ye. bakın. : //stackoverflow.com/a/36006948/141801

Böylece:

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

Bu yeni bir eklenti ve birçok mevcut ortamda çalışmayacak, örneğin Düğüm v8.7.0 bunu tanımıyor gibi görünüyor, ancak Chromium'da çalışıyor ve bunu bir yazım testinde kullanıyorum ve muhtemelen yazıyorum zaman geçtikçe daha yaygınlaşacak.


1
Bu, Chrome'da (v67) harika çalışıyor, ancak IE11 ve IEdge'de (v42) normal ifadeyi (ayrıca satır satır çalışmayı durduruyor) tamamen bozuyor
freedomn-m

Teşekkürler @ freedomn-m .. IE çok yeni bir özelliği desteklemiyor neredeyse tamamen şaşırtıcı :) Ama evet, neden kullanmaya çalıştıkları neden hata ayıklamaya çalışan kimseyi kurtarmak için kimseyi kurtarmak için işe yaramaz bahsetmeye değer beklenildiği gibi.
Neek

11

[.\n]işe yaramaz, çünkü nokta [](normal ifade tanımına göre; sadece javascript değil) nokta karakteri anlamına gelir. Bunun yerine (.|\n)(veya (.|[\n\r])) kullanabilirsiniz .


24
[\s\S]yeni satırlar dahil her şeyi eşleştirmek için kullanılan en yaygın JavaScript deyimidir. Gözler için daha kolay ve alternatif tabanlı bir yaklaşımdan çok daha verimli (.|\n). (Bu kelimenin tam anlamıyla "herhangi bir karakter anlamına olduğu boşluk veya herhangi bir karakteri değildir . Boşluk)
Alan Moore

2
Haklısın, ama soru ilgiliydi .ve \nve neden [.\n]iş yapmaz. Soruda belirtildiği gibi [^], aynı zamanda güzel bir yaklaşımdır.
Y. Shoham

6

Ben test (Chrome) ve benim için (hem [^]ve [^\0]), nokta ( .) [^\0]veya birini değiştirerek çalışıyor [^], çünkü nokta satır sonu eşleşmiyor (Buraya bakınız:http://www.regular-expressions.info/dot.html ).

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


1
Sorun [^\0], Javascript dizelerinde boş karakterlere izin verilmesine rağmen boş karakterlerle eşleşmemesidir ( bu cevaba bakınız ).
Donald Duck

0

Yukarıda bahsedilen örneklere ek olarak, bir alternatiftir.

^[\\w\\s]*$

Nerede \wkelimeleri ve \sbeyaz alanlar içindir

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.