JavaScript normal ifade çok satırlı bayrağı çalışmıyor


265

HTML'den dize almak için bir regex yazdım, ancak çok satırlı bayrak çalışmıyor gibi görünüyor.

Bu benim modelim ve metni h1etikete almak istiyorum .

var pattern= /<div class="box-content-5">.*<h1>([^<]+?)<\/h1>/mi
m = html.search(pattern);
return m[1];

Test etmek için bir dize oluşturdum. Dize "\ n" içerdiğinde, sonuç her zaman null olur. Tüm "\ n" leri kaldırsaydım, /mbayraklı olsun olmasın bana doğru sonucu verdi .

Normal ifademin nesi var?


14
HTML'yi ayrıştırmak için normal ifadeler kullanmayın, HTML normal bir dil DEĞİLDİR. Bir HTML ayrıştırıcı kullanın, sırasıyla. DOM. Bu da çok daha basit.
— Svante

Çok satırlı değil DOTALL'u arıyorsunuz.
— Vanuan

Yakında JavaScript'in dotAlldeğiştiriciye sahip olacağını ve böylece /.../snoktalarınızın yeni satırlarla eşleşeceğini unutmayın. Temmuz 2017 itibariyle, Chrome'daki bir bayrağın arkasında.

Yanıtlar:


609

Dotall değiştiricisi /.../solarak da bilinen değiştiriciyi arıyorsunuz . Noktayı, varsayılan olarak yapmadığı yeni satırlarla da eşleşmeye zorlar ..

Kötü haber, JavaScript'te bulunmamasıdır (ES2018'den beri var, aşağıya bakın) . İyi haber şu ki, bir karakter sınıfını (örn. \s) Ve olumsuzluğunu ( \S) birlikte kullanarak şöyle çalışabilirsiniz :

[\s\S]

Yani sizin durumunuzda normal ifade şöyle olur:

/<div class="box-content-5">[\s\S]*<h1>([^<]+?)<\/h1>/i

ES2018 itibariyle JavaScript destekleyen syüzden yazdım gibi düzenli ifade olabilir modern bir ortamda, (dotall) bayrağı, ancak bir ile ssonunda bayrağı (ziyade m; mdeğişiklikleri nasıl ^ve $iş, değil .):

/<div class="box-content-5">.*<h1>([^<]+?)<\/h1>/is

5
@simo Herhangi bir karakteri eşleştirerek, boşluk veya boşluk olmayan karakterlerle eşleşir. Bu gibidir ., ancak eşleşen boşluk da ( \s) eşleştiği anlamına gelir \n( .JavaScript'te yapılmaz veya sbayrakla yapılabilir).
— alex

1
Bu yanıt, "Değiştiriciler" altında Yığın Taşması Düzenli İfade SSS'ye eklendi .
— aliteralmind

40
MDN'ye göre [^], JavaScript'te yeni satırlar da dahil olmak üzere herhangi bir karakteri eşleştirmek için çalışıyor. Bkz. Developer.mozilla.org/tr-TR/docs/Web/JavaScript/Reference/…
— Dan Allen

6
Performans sorunları için, açgözlülüğü önlemek için *?nicelik belirtecinin kullanılması önemle tavsiye edilir *. Bu , belgenin son <h1> 'ını yakalamaktan kaçınacaktır : muhtemelen istediğiniz şey bu değildir ve regexp, daha önce bulmuş olsa bile dizenin sonuna kadar <h1> aramaya devam edeceği için bu etkili değildir.
— KrisWebDev

9
[^] Sürümü regexp derleyicisinde çok daha kolay ve aynı zamanda daha kısa.
— Erik Corry

21

Sen istiyorsun sanlaşılan JavaScript yok (dotall) değiştirici, - sen yerine .sahip [\ s \ S] @molf tarafından önerildiği gibi. m(Multiline) değiştirici markaları ^ $ ve maç hatları tamamı yerine dize.


4
/ S "değiştiricisinin çok satırlı modun aksine tek satır modunu ayarladığını ekleyebilirsiniz. +1
— Cerebrus

Dokuz yıl sonra JavaScript artık sbayrağa sahip (ES2018). :-)
— TJ Crowder

12

[\s\S]benim için işe yaramadı nodejs 6.11.3. Dayanarak RegExp belgelerine , kullanmak için diyor [^]benim için çalışır hangi.

(Nokta, ondalık noktası), satır sonlandırıcılar dışında herhangi bir karakterle eşleşir: \ n, \ r, \ u2028 veya \ u2029.

Bir karakter kümesinin içinde, nokta özel anlamını kaybeder ve gerçek bir nokta ile eşleşir.

M çok satırlı bayrağın nokta davranışını değiştirmediğini unutmayın. Dolayısıyla, bir kalıbı birden çok satırda eşleştirmek için [^] karakter kümesi kullanılabilir (elbette eski bir IE sürümü anlamına gelmezse), yeni satırlar dahil herhangi bir karakterle eşleşir.

Örneğin:

/This is on line 1[^]*?This is on line 3/m

nerede *? [^] 0 veya daha fazla tekrarlanan açgözlü kapamadır.


1
Ne [^]anlama geldiğini merak edenler için : bu bir çifte olumsuzlama gibidir: " bu boş listede olmayan herhangi bir karakteri eşleştir " ve böylece "herhangi bir karakteri eşleştir" demeye gelir .
— trincot


0

Benim önerim, çok satırlı dizeyi "\ n" ile bölmenin ve orijinal dizenin bölümlerini birleştirmenin daha iyi olması ve tek bir satır haline gelmesi ve kullanımı kolay olmasıdır.

<textarea class="form-control" name="Body" rows="12" data-rule="required" 
                  title='@("Your feedback ".Label())'
                  placeholder='@("Your Feedback here!".Label())' data-val-required='@("Feedback is required".Label())'
                  pattern="^[0-9a-zA-Z ,;/?.\s_-]{3,600}$" data-val="true" required></textarea>


$( document ).ready( function() {
  var errorMessage = "Please match the requested format.";
  var firstVisit = false;

  $( this ).find( "textarea" ).on( "input change propertychange", function() {

    var pattern = $(this).attr( "pattern" );
    var element = $( this );

    if(typeof pattern !== typeof undefined && pattern !== false)
    {
      var ptr = pattern.replace(/^\^|\$$/g, '');
      var patternRegex = new RegExp('^' + pattern.replace(/^\^|\$$/g, '') + '$', 'gm');     

      var ks = "";
      $.each($( this ).val().split("\n"), function( index, value ){
        console.log(index + "-" + value);
        ks += " " + value;
      });      
      //console.log(ks);

      hasError = !ks.match( patternRegex );
      //debugger;

      if ( typeof this.setCustomValidity === "function") 
      {
        this.setCustomValidity( hasError ? errorMessage : "" );
      } 
      else 
      {
        $( this ).toggleClass( "invalid", !!hasError );
        $( this ).toggleClass( "valid", !hasError );

        if ( hasError ) 
        {
          $( this ).attr( "title", errorMessage );
        } 
        else
        {
          $( this ).removeAttr( "title" );
        }
      }
    }

  });
});
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.