कई रेखाओं पर जावास्क्रिप्ट रेगेक्स का उपयोग कैसे करें?


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

मैं चाहता हूं कि PRE ब्लॉक को उठाया जाए, भले ही यह newline वर्णों पर फैला हो। मुझे लगा कि 'एम' झंडा ऐसा करता है। नहीं करता।

पोस्ट करने से पहले यहाँ जवाब मिला । मैंने सोचा था कि मैं जावास्क्रिप्ट जानता था (तीन किताबें पढ़ी, घंटों काम किया) और एसओ में कोई मौजूदा समाधान नहीं था, मैं वैसे भी पोस्ट करने की हिम्मत करूंगा। यहाँ पत्थर फेंको

तो समाधान है:

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

क्या किसी के पास कम गूढ़ तरीका है?

संपादित करें: यह एक डुप्लिकेट है, लेकिन चूंकि यह मेरी तुलना में कठिन है, इसलिए मैं नहीं हटाता।

यह [^]एक "मल्टीलाइन डॉट" के रूप में प्रस्तावित करता है। मुझे अभी भी समझ नहीं आ रहा है कि [.\n]काम क्यों नहीं होता है। लगता है कि यह जावास्क्रिप्ट के उदास भागों में से एक है ..


29
एक कम गुप्त रीगेक्स? असंभव, स्वभाव से।
रबेंस फरियास

btw, आपको पढ़ना चाहिए: "पार्सिंग एचटीएमएल: द सेथुलु
रूबेंस

1
पिछली टिप्पणी से लिंक बदल गया: blog.codinghorror.com/parsing-html-the-cthulhu-way (5yrs-ish later)
dab

जवाबों:


248

[.\n]काम नहीं करता है क्योंकि .अंदर कोई विशेष अर्थ नहीं है [], यह सिर्फ एक शाब्दिक अर्थ है .(.|\n)"न्यूलाइन सहित किसी भी वर्ण" को निर्दिष्ट करने का एक तरीका होगा। यदि आप सभी नई सूचियों का मिलान करना चाहते हैं, तो आपको \rविंडोज और क्लासिक मैक ओएस स्टाइल लाइन एंडिंग को शामिल करने की आवश्यकता होगी (.|[\r\n]):।

यह कुछ बोझिल हो जाता है, साथ ही साथ धीमा भी होता है, ( विवरणों के लिए क्रिस्बडेव का उत्तर देखें ), इसलिए सभी व्हाट्सएप पात्रों और सभी गैर-व्हाट्सएप पात्रों के साथ मेल खाने के लिए एक बेहतर तरीका होगा [\s\S], जो सब कुछ मैच करेगा, और तेज है और सरल होते हैं।

सामान्य तौर पर, आपको वास्तविक HTML टैग्स से मिलान करने के लिए एक regexp का उपयोग करने का प्रयास नहीं करना चाहिए। उदाहरण के लिए, इन सवालों के बारे में अधिक जानकारी के लिए देखें।

इसके बजाय, वास्तव में आपके द्वारा आवश्यक टैग के लिए DOM खोजने की कोशिश करें (jQuery का उपयोग करने से यह आसान हो जाता है, लेकिन आप हमेशा document.getElementsByTagName("pre")मानक DOM के साथ कर सकते हैं ), और फिर उन परिणामों की पाठ सामग्री को एक regexp के साथ खोजें, यदि आपको सामग्री के विरुद्ध मिलान करने की आवश्यकता है ।


मैं जो कर रहा हूं वह जावास्क्रिप्ट का उपयोग करके .wiki -> HTML रूपांतरण है। इसलिए, मेरे पास DOM उपलब्ध नहीं है, फिर भी। विकी फाइल ज्यादातर इसका अपना सिंटैक्स होता है, लेकिन मैं जरूरत पड़ने पर HTML टैग्स का उपयोग करने की अनुमति देता हूं। आपकी सलाह बहुत मान्य है, अगर मैं इसके साथ डोम में काम कर रहा था। धन्यवाद। :)
उर्फुपी

काफी उचित। मुझे लगता है कि HTML पर regexes का उपयोग करने के लिए एक वैध कारण है, हालांकि HTML के साथ मिश्रित विकी सिंटैक्स सभी प्रकार के मजेदार कोने के मामले हो सकते हैं।
ब्रायन कैंपबेल

2
[\r\n]एक अनुक्रम \ r \ n पर लागू होता है, पहले \ r और फिर \ n से मेल खाता है। यदि आप एक बार में पूरे अनुक्रम का मिलान करना चाहते हैं, भले ही वह अनुक्रम \ r \ n या सिर्फ \ n हो, पैटर्न का उपयोग करें.|\r?\n
Eirik Birkeland

1
एक पूरे मल्टीलाइन स्ट्रिंग से मिलान करने के लिए , लालची का प्रयास करें [\s\S]+
बोअज

मैं केवल पोस्टरिटी के लिए जोड़ना चाहता हूं कि जेएस रेगेक्स सिंटैक्स .अंदर के अर्थ को अनदेखा करता है, अन्य रेगेक्स फ्रेमवर्क की तुलना []में अलग है, विशेष रूप से .NET में उन्नत। लोग, कृपया यह न समझें कि रेग्जेस क्रॉस प्लेटफॉर्म हैं, वे अक्सर नहीं होते हैं !!
मिस्टर टीए

330

बहु-मिलान के (.|[\r\n])बजाय इसका उपयोग न करें .

मल्टीलाइन मैचिंग के [\s\S]बदले इस्तेमाल करें.

इसके अलावा, से बचने के लालच का उपयोग करके की जरूरत नहीं है, जहां *?या +?बजाय परिमाणक *या +। यह एक बहुत बड़ा प्रदर्शन प्रभाव डाल सकता है।

मैंने जो बेंचमार्क बनाया है, उसे देखें: http://jsperf.com/javascript-multiline-regexp-workedounds

Using [^]: fastest
Using [\s\S]: 0.83% slower
Using (.|\r|\n): 96% slower
Using (.|[\r\n]): 96% slower

NB: आप भी उपयोग कर सकते हैं [^]लेकिन यह नीचे टिप्पणी में पदावनत है।


22
अच्छे अंक, लेकिन मैं [^]वैसे भी उपयोग करने के खिलाफ सलाह देता हूं । एक तरफ, जावास्क्रिप्ट केवल स्वाद है जो मुझे पता है कि उस मुहावरे का समर्थन करता है, और यहां तक ​​कि इसका उपयोग कहीं नहीं है जितनी बार निकट है [\s\S]। दूसरी ओर, अधिकांश अन्य स्वाद आपको ]पहले सूचीबद्ध करके बच निकलने देते हैं । दूसरे शब्दों में, जावास्क्रिप्ट में [^][^]किसी भी दो से मेल खाता है, लेकिन नेट में यह किसी भी मेल खाता है एक से चरित्र अन्य ], [, या ^
एलन मूर

1
आपको कैसे पता चलेगा कि \Sमैच होगा \rया \nकिसी और किरदार से?
गिली

3
देखें इस सवाल \ s \ एस जानकारी के लिए। यह सभी सफेद-अंतरिक्ष वर्णों + सभी गैर-व्हाट्सएप पात्रों = सभी वर्णों से मेल करने के लिए एक हैक है। विशेष चरित्र प्रलेखन regexp के लिए MDN भी देखें ।
क्रिशवेबदेव

4
[\s\S]दूसरों पर पसंद करने का कोई कारण , जैसे [\d\D]या [\w\W]?
फ्रॉग्ज

1
मुझे जल्दी से संकेत दें कि लालची ऑपरेटर के लिए आपका परीक्षण धांधली है। /<p>Can[^]*?<\/p>/के रूप में एक ही सामग्री से मेल नहीं खाता /<p>Can[^]*<\/p>/। लालची संस्करण को /<p>(?:[^<]|<(?!\/p>))*<\/p>/उसी सामग्री से मेल खाने के लिए बदला जाना चाहिए ।
3limin4t0r

19

आप अपने पर्यावरण और जावास्क्रिप्ट के संस्करण (ECMAscript) को निर्दिष्ट नहीं करते हैं, और मुझे लगता है कि यह पोस्ट 2009 से थी, लेकिन पूर्णता के लिए, ECMA2018 की रिलीज़ के साथ अब हम sध्वज का उपयोग करके .'\ n' से मिलान कर सकते हैं , देखें https : //stackoverflow.com/a/36006948/141801

इस प्रकार:

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

यह एक हालिया जोड़ है और कई वर्तमान परिवेशों में काम नहीं करेगा, उदाहरण के लिए नोड v8.7.0 इसे पहचानता प्रतीत नहीं होता है, लेकिन यह क्रोमियम में काम करता है, और मैं इसे एक टाइपस्क्रिप्ट परीक्षा में उपयोग कर रहा हूं और लिख रहा हूं। समय बीतने के साथ और अधिक मुख्यधारा बन जाएगी।


1
यह क्रोम (v67) में बहुत अच्छा काम करता है, लेकिन IE11 और IEdge (v42) में रेगेक्स (काम करने वाली लाइन-बाय-लाइन को भी रोक देता है) को पूरी तरह से तोड़ता है
स्वतंत्रता-

धन्यवाद @ स्वतंत्रता-एम .. आईई एक बहुत नई सुविधा का समर्थन नहीं करना लगभग पूरी तरह से चौंकाने वाला है :) लेकिन हां, यह ध्यान देने योग्य है कि जहां यह किसी को भी 'डिबग' करने की कोशिश करने से बचाने के लिए काम नहीं करता है, तो उनका उपयोग करने का प्रयास क्यों काम नहीं कर रहा है जैसा सोचा था।
नीक

11

[.\n]काम नहीं करता है, क्योंकि डॉट इन [](regex परिभाषा द्वारा; केवल जावास्क्रिप्ट नहीं) का अर्थ है डॉट-कैरेक्टर। आप इसके बजाय (.|\n)(या (.|[\n\r])) का उपयोग कर सकते हैं ।


24
[\s\S]newlines सहित सब कुछ मिलान के लिए सबसे आम जावास्क्रिप्ट मुहावरा है। यह आंखों पर आसान है और एक वैकल्पिक-आधारित दृष्टिकोण की तुलना में बहुत अधिक कुशल है (.|\n)। (यह सचमुच किसी भी चरित्र इसका मतलब है कि " है खाली स्थान या किसी भी चरित्र है कि नहीं है । खाली स्थान के)
एलन मूर

2
आप सही हैं, लेकिन सवाल यह था .और \n, और [.\n]यह काम क्यों नहीं करता। जैसा कि प्रश्न में कहा गया है, [^]अच्छा दृष्टिकोण भी है।
वाई। शोहम

6

मैंने (क्रोम) इसका परीक्षण किया है और यह मेरे लिए (दोनों ) [^]और [^\0], या .तो डॉट ( ) को बदलकर काम कर रहा है , क्योंकि डॉट लाइन ब्रेक से मेल नहीं खाता (यहां देखें:[^\0][^]http://www . अनियमित-expressions.info/dot.html )।

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


1
इसके साथ समस्या [^\0]यह है कि यह अशक्त वर्णों से मेल नहीं खाएगा, जबकि जावास्क्रिप्ट वर्णों में अशक्त वर्णों की अनुमति है ( यह उत्तर देखें )।
डोनाल्ड डक

0

उपर्युक्त उदाहरणों के अलावा, यह एक वैकल्पिक है।

^[\\w\\s]*$

जहां \wशब्दों के लिए है और \sसफेद रिक्त स्थान के लिए है

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