जावास्क्रिप्ट रेगेक्स मल्टीलाइन फ्लैग काम नहीं करता है


265

मैंने HTML से स्ट्रिंग लाने के लिए एक रेगेक्स लिखा था, लेकिन ऐसा लगता है कि मल्टीलाइन ध्वज काम नहीं करता है।

यह मेरा पैटर्न है और मैं h1टैग में पाठ प्राप्त करना चाहता हूं ।

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

मैंने इसका परीक्षण करने के लिए एक स्ट्रिंग बनाई। जब स्ट्रिंग में "\ n" होता है, तो परिणाम हमेशा शून्य होता है। अगर मैंने सभी "\ n" s हटा दिया, तो इससे मुझे सही परिणाम मिला, /mझंडे के साथ या उसके बिना कोई बात नहीं ।

मेरे रेक्सक्स में क्या गलत है?


14
HTML को पार्स करने के लिए नियमित अभिव्यक्तियों का उपयोग न करें, HTML एक नियमित भाषा नहीं है। HTML पार्सर का उपयोग करें, सम्मान करें। डोम। यह भी बहुत सरल है।
Svante

आप DOTALL की तलाश कर रहे हैं, न कि मल्टीलाइन की।
वानुआन

ध्यान दें कि जावास्क्रिप्ट जल्द ही होगाdotAll आप ऐसा कर सकते हैं संशोधक /.../sऔर अपने डॉट्स भी नई लाइनों का मिलान करेंगे। जुलाई 2017 तक यह क्रोम में एक ध्वज के पीछे है।

जवाबों:


609

आप /.../sसंशोधक की तलाश कर रहे हैं , जिसे dotall modifier के रूप में भी जाना जाता है । यह डॉट .को नई संख्याओं से मेल खाने के लिए मजबूर करता है, जो वह डिफ़ॉल्ट रूप से नहीं करता है।

बुरी खबर यह है कि यह जावास्क्रिप्ट में मौजूद नहीं है (यह ES2018 के अनुसार होता है, नीचे देखें) । अच्छी खबर यह है कि आप एक चरित्र वर्ग (जैसे \s) और इसके निषेध ( \S) को एक साथ उपयोग करके इसके चारों ओर काम कर सकते हैं, जैसे:

[\s\S]

तो आपके मामले में regex बन जाएगा:

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

ES2018 के अनुसार, जावास्क्रिप्ट s(dotAll) ध्वज का समर्थन करता है , इसलिए एक आधुनिक वातावरण में आपकी नियमित अभिव्यक्ति हो सकती है जैसा कि आपने इसे लिखा था, लेकिन sअंत में एक ध्वज के साथ (बजाय m, mपरिवर्तन कैसे ^और $काम करता है, नहीं .):

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

5
@ सिमो किसी भी व्हाट्सएप या गैर व्हाट्सएप चरित्र से मेल खाता है, प्रभावी रूप से किसी भी चरित्र से मेल खाता है। यह पसंद है ., लेकिन व्हाट्सएप का मिलान भी ( \s) का अर्थ है यह मेल खाता है \n(जो .जावास्क्रिप्ट में नहीं है, या sध्वज के साथ करने के लिए बनाया जा सकता है )।
एलेक्स

1
इस उत्तर को "संशोधक" के तहत स्टैक ओवरफ्लो रेगुलर एक्सप्रेशन एफएक्यू में जोड़ा गया है ।
aliteralmind

40
MDN के अनुसार [^], जावास्क्रिप्ट में newlines सहित किसी भी चरित्र से मेल खाने के लिए भी काम करता है। देखें developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
दान एलन

6
प्रदर्शन के मुद्दों के लिए, लालच से बचने के लिए *?क्वांटिफायर का उपयोग करने की अत्यधिक अनुशंसा की जाती है *। यह दस्तावेज़ के अंतिम <h1> को पकड़ने से बच जाएगा : यह शायद वह नहीं है जो आप चाहते हैं और जो कुशल नहीं है क्योंकि regexp <h1> को तब तक देखना जारी रखेगा जब तक कि स्ट्रिंग के अंत में यह पहले से ही मिल गया हो।
क्रिशवेबदेव

9
[^] संस्करण regexp संकलक पर आसान है, और अधिक सुस्पष्ट भी है।
एरिक कोरी

21

आप s(dotall) संशोधक चाहते हैं, जो जाहिर तौर पर जावास्क्रिप्ट में मौजूद नहीं है - आप .@molf द्वारा सुझाए गए अनुसार [\ _ s] को बदल सकते हैं। m(बहु) संशोधक बनाता ^ और $ मैच लाइनों के बजाय पूरी स्ट्रिंग।


4
आप जोड़ सकते हैं कि "s" संशोधक एकल मोड के रूप में मल्टीलाइन मोड के विपरीत सेट करता है। +1
सेरेब्रस

नौ साल बाद, जावास्क्रिप्ट में अब sध्वज (ES2018) है। :-)
टीजे क्राउडर

12

[\s\S]मेरे लिए नोडज 6.11.3 में काम नहीं किया। RegExp प्रलेखन के आधार पर , यह उपयोग करने के लिए कहता है [^]जो मेरे लिए काम करता है।

(डॉट, दशमलव बिंदु) लाइन टर्मिनेटर को छोड़कर किसी भी एकल वर्ण से मेल खाता है: \ n, \ r, \ u2028 या \ u2029।

एक वर्ण सेट के अंदर, डॉट अपना विशेष अर्थ खो देता है और शाब्दिक बिंदु से मेल खाता है।

ध्यान दें कि एम मल्टीलाइन ध्वज डॉट व्यवहार नहीं बदलता है। इसलिए, कई लाइनों में एक पैटर्न से मेल खाने के लिए, वर्ण सेट [^] का उपयोग किया जा सकता है (यदि आपके पास IE का एक पुराना संस्करण नहीं है, तो निश्चित रूप से), यह नए वर्णों सहित किसी भी चरित्र से मेल खाएगा।

उदाहरण के लिए:

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

जहां *? गैर-लालची हड़पने की 0 या उससे अधिक की घटनाएँ हैं [^]।


1
उन लोगों के लिए जो आश्चर्य करते हैं कि [^]इसका क्या मतलब है: यह एक दोहरे नकार की तरह है: "किसी भी चरित्र का मिलान करें जो इस खाली सूची में नहीं है " और इसलिए यह "किसी भी चरित्र से मेल खाने वाले" कहने के लिए नीचे आता है ।
बजे

8

Dotall संशोधक ने वास्तव में इसे जून 2018 में जावास्क्रिप्ट में बनाया है, जो कि ECMAScript 2018 है।
https://github.com/tc39/proposal-regexp-dotall-flag

const re = /foo.bar/s; // Or, `const re = new RegExp('foo.bar', 's');`.
re.test('foo\nbar');
// → true
re.dotAll
// → true
re.flags
// → 's'

0

मेरा सुझाव है कि "\ n" के साथ कई-लाइन स्ट्रिंग को विभाजित करना बेहतर है और मूल स्ट्रिंग के विभाजन को समेटना और एक ही लाइन और हेरफेर करना आसान है।

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

  });
});
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.