जावास्क्रिप्ट में दो तारों के बीच एक स्ट्रिंग प्राप्त करने के लिए नियमित अभिव्यक्ति


166

मुझे बहुत समान पोस्ट मिले हैं, लेकिन मैं अपनी नियमित अभिव्यक्ति को यहां नहीं ला सकता।

मैं एक नियमित अभिव्यक्ति लिखने की कोशिश कर रहा हूं जो एक स्ट्रिंग देता है जो दो अन्य तारों के बीच है। उदाहरण के लिए: मैं उस स्ट्रिंग को प्राप्त करना चाहता हूं जो स्ट्रिंग्स "गाय" और "दूध" के बीच रहता है।

मेरी गाय हमेशा दूध देती है

लौटूंगा

"हमेशा देता है"

यहाँ अभिव्यक्ति है जो मैंने अब तक एक साथ पाई है:

(?=cow).*(?=milk)

हालांकि, यह स्ट्रिंग "गाय हमेशा देता है" देता है।


6
मैं इस पुराने सवाल पर लड़खड़ा गया और स्पष्ट करना चाहता था कि टेस्ट्रे एक सरणी क्यों है। test.match, कुल मिलान के रूप में पहले अनुक्रमणिका के साथ एक सरणी देता है (तत्संबंधी, वह स्ट्रिंग जो गाय (? *) दूध से मेल खाता है) और फिर, सभी फंसे हुए तार जैसे (। *) यदि वहाँ कोष्ठक का दूसरा सेट होता है। उसके बाद टेस्ट्रे में हो [2]
सैल्केट

4
यदि आप एक स्ट्रिंग को खोज रहे हैं, तो यह समाधान काम नहीं करेगा। ऐसी स्थिति में, आपको "STRING_ONE ([\\ s \\ S] *?) STRING_TWO" का उपयोग करना चाहिए। stackoverflow.com/questions/22531252/...
Michael.Lumley

जवाबों:


183

एक लुकहेड (वह (?=हिस्सा) किसी इनपुट का उपभोग नहीं करता है। यह एक शून्य-चौड़ाई का दावा है (जैसा कि सीमा जाँच और लुकहाइंड हैं)।

आप यहाँ एक नियमित मैच चाहते हैं, cowभाग का उपभोग करने के लिए । बीच के हिस्से पर कब्जा करने के लिए, आप एक कैप्चरिंग ग्रुप का उपयोग करते हैं (सिर्फ उस पैटर्न के हिस्से को रखें जिसे आप कोष्ठक के अंदर कैप्चर करना चाहते हैं):

cow(.*)milk

किसी भी तरह के लुक की जरूरत नहीं होती है।


26
जब मैं इसका परीक्षण करता हूं, तो प्रदान की गई रेक्सक्स अभिव्यक्ति में "गाय" और "दूध" दोनों शामिल हैं ...
कास्केडियन

4
यह एक कदम याद आ रहा है। जब आपको मैच का परिणाम मिलता है, तो आपको पहले कैप्चर करने वाले समूह के मिलान वाले पाठ को निकालने की आवश्यकता होती है matched[1], न कि पूरे मिलान वाले पाठ के साथ matched[0]
रोरी ओ'केन

7
जावास्क्रिप्ट में, आपको वास्तव में इसके ([\s\S]*?)बजाय उपयोग करने की आवश्यकता है (.*?)
कियान चेन

7
यद्यपि यह एक उपयोगी तकनीक है, इसे डाउनवोट किया गया था क्योंकि IMHO यह सवाल का सही जवाब नहीं है, क्योंकि इसमें "गाय" और "दूध" शामिल हैं, जैसा कि @TheCascadian
Almir Campos

@AlmirCampos - अगर मुझसे गलती नहीं है तो "गाय" और "दूध" के मिलान के बिना इस मैच को करने का कोई तरीका नहीं है (चूंकि आप उन दोनों के बीच क्या है, इसका मिलान करना चाहते हैं)। समस्या खुद RegEx में नहीं है लेकिन आप इसे बाद में कैसे संभालते हैं (जैसा कि रोरी ओ'केन ने बताया है)। अन्यथा आप केवल आसपास के रिक्त स्थान के लिए मिलान कर सकते हैं - और यह आपको बहुत गलत रिटर्न देगा, है ना?
sborn

69

जावास्क्रिप्ट में दो तारों के बीच एक स्ट्रिंग प्राप्त करने के लिए नियमित अभिव्यक्ति

सबसे पूर्ण समाधान जो अधिकांश मामलों में काम करेगा, एक आलसी डॉट मिलान पैटर्न के साथ कैप्चरिंग समूह का उपयोग कर रहा है । हालांकि, एक डॉट जावास्क्रिप्ट regex में लाइन ब्रेक वर्णों से मेल नहीं खाता है, तो, क्या 100% मामलों में काम करेंगे एक है या / / निर्माणों।.[^][\s\S][\d\D][\w\W]

ECMAScript 2018 और नए संगत समाधान

ECMAScript 2018 का समर्थन करने वाले जावास्क्रिप्ट वातावरण में , sसंशोधक .किसी भी चार्ट को लाइन ब्रेक चार्ट सहित मिलान करने की अनुमति देता है, और रेगेक्स इंजन चर लंबाई के लुकबाइंड का समर्थन करता है। तो, आप एक regex का उपयोग कर सकते हैं

var result = s.match(/(?<=cow\s+).*?(?=\s+milk)/gs); // Returns multiple matches if any
// Or
var result = s.match(/(?<=cow\s*).*?(?=\s*milk)/gs); // Same but whitespaces are optional

दोनों मामलों में, वर्तमान स्थिति की जाँच cowकिसी 1/0 या अधिक व्हाट्सएप के साथ की जाती है cow, फिर किसी भी 0+ चार्ट को जितना संभव हो उतना मिलान किया जाता है और उपभोग किया जाता है (= मैच मूल्य में जोड़ा जाता है), और उसके बाद milkकिसी के साथ जांच की जाती है इस प्रतिस्थापन से पहले 1 / या अधिक व्हाट्सएप)।

परिदृश्य 1: सिंगल-लाइन इनपुट

यह और नीचे के अन्य सभी परिदृश्य सभी जावास्क्रिप्ट वातावरण द्वारा समर्थित हैं। उत्तर के नीचे उपयोग उदाहरण देखें।

cow (.*?) milk

cowपहले पाया जाता है, फिर एक स्थान, फिर लाइन ब्रेक चार्ज के अलावा कोई भी 0+ चार्ट, जितना संभव हो उतना *?आलसी क्वांटिफायर होता है, समूह 1 में कब्जा कर लिया जाता है और फिर एक स्थान milkका पालन करना चाहिए (और वे मेल खाते हैं और भस्म हो जाते हैं , भी) )।

परिदृश्य 2: बहुस्तरीय इनपुट

cow ([\s\S]*?) milk

यहां, cowऔर पहले एक स्पेस का मिलान किया जाता है, फिर किसी भी 0+ चार्ट को जितना संभव हो उतना कम मिलान किया जाता है और ग्रुप 1 में कैप्चर किया जाता है, और फिर एक स्पेस से milkमिलान किया जाता है।

परिदृश्य 3: ओवरलैपिंग मैच

यदि आपके पास एक स्ट्रिंग है >>>15 text>>>67 text2>>>और आपको >>>+ number+ whitespaceऔर के बीच में 2 मैच प्राप्त करने की आवश्यकता है >>>, तो आप इसका उपयोग नहीं कर सकते हैं />>>\d+\s(.*?)>>>/gक्योंकि यह केवल पहले मैच का पता लगाने पर पहले से भस्म>>> होने वाले तथ्य के कारण केवल 1 मैच होगा । आप वास्तव में "gobbling" के बिना पाठ उपस्थिति के लिए जाँच करने के लिए एक सकारात्मक रूपांतर का उपयोग कर सकते हैं (यानी मैच के लिए संलग्न):67

/>>>\d+\s(.*?)(?=>>>)/g

ऑनलाइन regex डेमो उपज text1और text2समूह 1 सामग्री के रूप में देखें ।

यह भी देखें कि स्ट्रिंग के लिए सभी संभावित अतिव्यापी मैचों को कैसे प्राप्त करें

प्रदर्शन के विचार

.*?रेगेक्स पैटर्न के अंदर आलसी डॉट मिलान पैटर्न ( ) बहुत लंबा इनपुट दिए जाने पर स्क्रिप्ट निष्पादन को धीमा कर सकता है। कई मामलों में, अनियंत्रित-लूप तकनीक अधिक हद तक मदद करती है। सभी के बीच cowऔर milkसे हड़पने की कोशिश करते हुए "Their\ncow\ngives\nmore\nmilk", हम देखते हैं कि हमें बस उन सभी लाइनों से मेल खाना है जो milkइस तरह से शुरू नहीं होते हैं , इस प्रकार, cow\n([\s\S]*?)\nmilkहम कर सकते हैं:

/cow\n(.*(?:\n(?!milk$).*)*)\nmilk/gm

रेगेक्स डेमो देखें (यदि हो सकता है \r\n, तो उपयोग करें /cow\r?\n(.*(?:\r?\n(?!milk$).*)*)\r?\nmilk/gm)। इस छोटे परीक्षण स्ट्रिंग के साथ, प्रदर्शन लाभ नगण्य है, लेकिन बहुत बड़े पाठ के साथ, आप अंतर महसूस करेंगे (विशेषकर यदि लाइनें लंबी हैं और लाइन ब्रेक बहुत अधिक नहीं हैं)।

जावास्क्रिप्ट में नमूना regex उपयोग:

//Single/First match expected: use no global modifier and access match[1]
console.log("My cow always gives milk".match(/cow (.*?) milk/)[1]);
// Multiple matches: get multiple matches with a global modifier and
// trim the results if length of leading/trailing delimiters is known
var s = "My cow always gives milk, thier cow also gives milk";
console.log(s.match(/cow (.*?) milk/g).map(function(x) {return x.substr(4,x.length-9);}));
//or use RegExp#exec inside a loop to collect all the Group 1 contents
var result = [], m, rx = /cow (.*?) milk/g;
while ((m=rx.exec(s)) !== null) {
  result.push(m[1]);
}
console.log(result);

आधुनिक String#matchAllपद्धति का उपयोग कर

const s = "My cow always gives milk, thier cow also gives milk";
const matches = s.matchAll(/cow (.*?) milk/g);
console.log(Array.from(matches, x => x[1]));


51

यहाँ एक रेगीक्स है जो गाय और दूध के बीच क्या ले जाएगा (प्रमुख / अनुगामी स्थान के बिना):

srctext = "My cow always gives milk.";
var re = /(.*cow\s+)(.*)(\s+milk.*)/;
var newtext = srctext.replace(re, "$2");

एक उदाहरण: http://jsfiddle.net/entropo/tkP74/


17
  • आपको कब्जा करने की आवश्यकता है .*
  • आप कर सकते हैं (लेकिन नहीं है) .*nongreedy बनाने के लिए
  • वास्तव में लुकहेड की कोई आवश्यकता नहीं है।

    > /cow(.*?)milk/i.exec('My cow always gives milk');
    ["cow always gives milk", " always gives "]

इस विशेष उदाहरण में, अगर यह लालची होता तो अंत तक पहुँच जाता और पीछे (संभवतः)।
बेन

9

चुना जवाब मेरे लिए काम नहीं किया ... हम्म ...

बस गाय से और / या दूध से पहले "हमेशा देता है" से रिक्त स्थान जोड़ने के लिए स्थान जोड़ें

/(?<=cow ).*(?= milk)/

यहां छवि विवरण दर्ज करें


आपको अपने स्वयं के उत्तर पर टिप्पणी करने की आवश्यकता नहीं है, बस इसे संपादित करें।
कोड़ी C

देखो पीछे ?<=जावास्क्रिप्ट में समर्थित नहीं है।
मार्क कारपेंटर जूनियर

@MarkCarpenterJr यदि आपने regextester.com के माध्यम से इसका परीक्षण किया , तो आपको वह संकेत मिल जाएगा। ऐसा लगता है कि साइट ने पुराने नियमों से अपने नियम बनाए हैं। लुकबाइंड अब समर्थित है। देखें stackoverflow.com/questions/30118815/... और पैटर्न त्रुटि के बिना आधुनिक ब्राउज़र के साथ अच्छी तरह से काम करता है। इस चेक को regex101.com
duduwe

@ CodyG.ah हाँ। समझ गया।
डुडुवे

8

मैं नीचे मार्टिनो फर्नांडीस के समाधान का उपयोग करके मुझे जो कुछ भी चाहिए था वह प्राप्त करने में सक्षम था। कोड है:

var test = "My cow always gives milk";

var testRE = test.match("cow(.*)milk");
alert(testRE[1]);

आप देखेंगे कि मैं एक सरणी के रूप में टेस्ट्रे चर को सचेत कर रहा हूं। इसका कारण यह है कि TestRE किसी कारण से एक सरणी के रूप में लौट रहा है। से उत्पादन:

My cow always gives milk

में परिवर्तन:

always gives

1
धन्यवाद, मैंने इसके लिए एक फिडेल ( jsfiddle.net/MoscaPt/g5Lngjx8/2 ) जोड़ा । / जोहान
मोस्को पं।

4

बस निम्नलिखित नियमित अभिव्यक्ति का उपयोग करें:

(?<=My cow\s).*?(?=\smilk)

देखो पीछे ?<=जावास्क्रिप्ट में समर्थित नहीं है। हालांकि यह करने का तरीका होगा।
मार्क कारपेंटर जूनियर

यह जावास्क्रिप्ट में समर्थित है। यह केवल क्रोम और ओपेरा में सफारी और मोज़िला (अभी तक) में समर्थित नहीं है।
पॉल स्ट्रूपेकिस

3

मुझे लगता है कि रेक्सक्स थकाऊ और समय लगता है जो सिंटैक्स दिया जाता है। चूंकि आप पहले से ही जावास्क्रिप्ट का उपयोग कर रहे हैं, यह regex के बिना निम्नलिखित करना आसान है:

const text = 'My cow always gives milk'
const start = `cow`;
const end = `milk`;
const middleText = text.split(start)[1].split(end)[0]
console.log(middleText) // prints "always gives"

2
मेरे लिये कार्य करता है! शानदार जवाब क्योंकि यह सिर्फ सच में आसान है! :)
एंड्रयू इरविन


0

विधि मिलान () एक मैच के लिए एक स्ट्रिंग खोजता है और एक ऐरे ऑब्जेक्ट देता है।

// Original string
var str = "My cow always gives milk";

// Using index [0] would return<br/>
// "**cow always gives milk**"
str.match(/cow(.*)milk/)**[0]**


// Using index **[1]** would return
// "**always gives**"
str.match(/cow(.*)milk/)[1]

0

कार्य

दो स्ट्रिंग के बीच विकल्प निकालें (इस दो स्ट्रिंग्स को छोड़कर)

उपाय

let allText = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum";
let textBefore = "five centuries,";
let textAfter = "electronic typesetting";
var regExp = new RegExp(`(?<=${textBefore}\\s)(.+?)(?=\\s+${textAfter})`, "g");
var results = regExp.exec(allText);
if (results && results.length > 1) {
    console.log(results[0]);
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.