भागते हुए उद्धरण के साथ उद्धृत स्ट्रिंग के लिए रेगेक्स


120

मैं " It's big \"problem "एक नियमित अभिव्यक्ति का उपयोग करके प्रतिस्थापन कैसे प्राप्त करूं ?

s = ' function(){  return " It\'s big \"problem  ";  }';     

1
आप एक स्ट्रिंग में "इट्स" कैसे पाते हैं जिसमें केवल "इज़" होता है? मैं आपके लिए इसे ठीक कर दूंगा, लेकिन मैं नहीं जानता कि आप जिस भाषा का उपयोग कर रहे हैं, उसमें कौन-से एकल-उद्धरण / एस्केप कन्वेंशन लागू होते हैं।
जोनाथन लेफ़लर

1
डुप्लिकेट ऑफ़: PHP:
रेग्क्स को

2
दरअसल, तारीखों को देखते हुए, मैं देखता हूं कि दूसरा प्रश्न इस एक की नकल है। किसी भी तरह से, मेरे उत्तर की जांच करना सुनिश्चित करें ।
रेजरगनर

@ridgerunner: जैसा कि आपने सुझाव दिया है, मैं इसे बंद करने के लिए मतदान कर रहा हूं। यह सच है अन्य प्रश्न हाल ही में अधिक है, लेकिन यह बहुत बेहतर है (ज्यादातर आपके उत्तर के लिए धन्यवाद)।
एलन मूर

जवाबों:


158
/"(?:[^"\\]|\\.)*"/

रेगेक्स कोच और पीसीआरई कार्यक्षेत्र में काम करता है।

जावास्क्रिप्ट में परीक्षण का उदाहरण:

    var s = ' function(){ return " Is big \\"problem\\", \\no? "; }';
    var m = s.match(/"(?:[^"\\]|\\.)*"/);
    if (m != null)
        alert(m);


23
समझ में आता है। प्लेन इंग्लिश: शून्य के आसपास के दो उद्धरण या "किसी भी वर्ण कि एक उद्धरण या एक बैकस्लैश नहीं है" या "किसी भी चरित्र द्वारा पीछा बैकस्लैश"। मुझे विश्वास नहीं हो रहा है कि मैंने ऐसा करने के लिए नहीं सोचा था ...
Ajedi32

7
मैं खुद जवाब दूंगा। =) (?:...)एक निष्क्रिय या गैर-कैप्चरिंग समूह है। इसका मतलब है कि इसे बाद में वापस नहीं किया जा सकता है।
मगसर

बहुत खोज करने और बहुत परीक्षण करने के बाद यह मेरी इस सामान्य समस्या का वास्तविक और एकमात्र समाधान है। धन्यवाद!
कैंसरबेरो

9
इसके लिए धन्यवाद। मैं सिंगल कोट्स को भी मैच करना चाहता था इसलिए मैंने इसे इस /(["'])(?:[^\1\\]|\\.)*?\1/
लेओ

इसके साथ var s = ' my \\"new\\" string and \"this should be matched\"';, इस दृष्टिकोण से अप्रत्याशित परिणाम प्राप्त होंगे।
विकटोरिया स्ट्राइब्यू जुवे

32

यह एक linux distros में उपलब्ध nanorc.sample से आता है। इसका उपयोग C स्टाइल स्ट्रिंग्स के सिंटैक्स हाइलाइटिंग के लिए किया जाता है

\"(\\.|[^\"])*\"

इसके साथ var s = ' my \\"new\\" string and \"this should be matched\"';, इस दृष्टिकोण से अप्रत्याशित परिणाम प्राप्त होंगे।
विकटोरिया स्ट्राइब्यू जुवे

1
c.nanorc सबसे पहले मैं गया था। एक सी स्ट्रिंग शाब्दिक के हिस्से के रूप में काम करने के लिए इसे तब तक नहीं मिला जब तक कि सब कुछ इस तरह से बच न जाए" \"(\\\\.|[^\\\"])*\" "
नरकंकाल

यह libre से egrep और re_comp / re_exec फ़ंक्शन के साथ काम करता है।
fk0

19

जैसा कि ePharaoh द्वारा प्रदान किया गया है, इसका उत्तर है

/"([^"\\]*(\\.[^"\\]*)*)"/

उपरोक्त उद्धृत करने के लिए या तो एकल उद्धृत या डबल उद्धृत स्ट्रिंग का उपयोग करें

/"([^"\\]*(\\.[^"\\]*)*)"|\'([^\'\\]*(\\.[^\'\\]*)*)\'/

2
यह एकमात्र सेट है जो मेरे लिए एक एकल, बड़े 1.5 KB उद्धृत स्ट्रिंग के साथ काम करता है जिसमें 99 एस्केप हैं। इस पृष्ठ पर हर दूसरी अभिव्यक्ति मेरे पाठ संपादक में एक अतिप्रवाह त्रुटि के साथ टूट गई। हालांकि यहां ज्यादातर ब्राउज़र में काम करते हैं, बस कुछ ध्यान में रखना है। फिडल: jsfiddle.net/aow20y0L
Beejor

3
स्पष्टीकरण के लिए नीचे @ MarcAndrePoulin का उत्तर देखें।
21

10

यहां दिए गए अधिकांश समाधान वैकल्पिक पुनरावृत्ति पथों का उपयोग करते हैं अर्थात (ए | बी) *।

आप बड़े इनपुट पर स्टैक ओवरफ्लो का सामना कर सकते हैं क्योंकि कुछ पैटर्न कंपाइलर पुनरावृत्ति का उपयोग करके इसे लागू करता है।

उदाहरण के लिए जावा: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=63333993

कुछ इस तरह से: "(?:[^"\\]*(?:\\.)?)*"या गाइ बेडफोर्ड द्वारा प्रदान किए गए एक सबसे स्टैक ओवरफ्लो से बचने के लिए पार्सिंग चरणों की मात्रा कम हो जाएगी।


9
"(?:\\"|.)*?"

अल्टरनेटिंग क्वांटिफायर यह सुनिश्चित करता है कि आलसी क्वांटिफायर से गुजरते समय आपस में \"और .पास से बाहर निकलने वाले कोट्स को छोड़ दें *?। .NET फ्रेमवर्क आरई कक्षाओं के साथ काम करता है


लेकिन विफल रहता है"\\"
इयान


/"(?:(?:\\"|[^"])*)"/gइसे ठीक करना चाहिए
डेव

7
/"(?:[^"\\]++|\\.)*+"/

man perlreएक लिनक्स सिस्टम पर सीधे से लिया गया है जिसमें पर्ल 5.22.0 स्थापित है। एक अनुकूलन के रूप में, यह रेगेक्स दोनों के 'पॉजेसिव' रूप का उपयोग करता है +और *बैकट्रैकिंग को रोकने के लिए, क्योंकि यह पहले से ही जाना जाता है कि क्लोजिंग उद्धरण के बिना एक स्ट्रिंग किसी भी मामले में मेल नहीं खाएगी।


4
/(["\']).*?(?<!\\)(\\\\)*\1/is

किसी भी उद्धृत स्ट्रिंग के साथ काम करना चाहिए


1
अच्छा है, लेकिन अनुरोध के लिए बहुत लचीला है (एकल उद्धरण से मेल खाएगा ...)। और जब तक कि मुझे कुछ याद न हो / सरलीकृत किया जा सकता है /".*?(?<=\)"/ ओह, और कुछ भाषाएं (उदाहरण के लिए। जावास्क्रिप्ट) अलास नकारात्मक दिखावटी भावों को नहीं समझती हैं।
फीलो

1
@PhiLho, केवल एक का उपयोग करके (?!! \\) स्ट्रिंग के अंत में बच गए बैकस्लैश पर विफल होगा। हालाँकि जावास्क्रिप्ट में लुक-बिहाइंड के बारे में सही है।
मार्कस जार्डेरोट 8

4

यह एक PCRE पर सही काम करता है और StackOverflow के साथ नहीं आता है।

"(.*?[^\\])??((\\\\)+)?+"

स्पष्टीकरण:

  1. हर उद्धृत स्ट्रिंग चार से शुरू होता है ":;
  2. इसमें किसी भी वर्ण की संख्या शामिल हो सकती है: .*?{आलसी मैच}; गैर पलायन चरित्र के साथ समाप्त [^\\];
  3. कथन (2) आलसी (!) वैकल्पिक है क्योंकि स्ट्रिंग खाली हो सकती है ("")। इसलिए:(.*?[^\\])??
  4. अंत में, प्रत्येक उद्धृत स्ट्रिंग चार ( ") के साथ समाप्त होता है , लेकिन यह भागने के संकेत जोड़े की संख्या के साथ भी हो सकता है (\\\\)+; और यह लालची (!) वैकल्पिक है: ((\\\\)+)?+{लालची मिलान}, बेकेज स्ट्रिंग जोड़े को समाप्त किए बिना या खाली हो सकता है!

यह दुनिया का सबसे कुशल पैटर्न नहीं है, लेकिन विचार दिलचस्प है। ध्यान दें कि आप इसे इस तरह छोटा कर सकते हैं:"(.*?[^\\])?(\\\\)*"
कासिमिर एट

2

यहाँ एक है जो दोनों "और 'के साथ काम करता है और आप शुरू में दूसरों को आसानी से जोड़ते हैं।

( "| ') (? \\\ 1 | [^ \ 1])? * \ 1

यह बैकरेफेरेंस (\ 1) मैच का उपयोग करता है जो पहले समूह ("या ') में है।

http://www.regular-expressions.info/backref.html


यह एक बहुत अच्छा समाधान है, लेकिन [^\1]इसके साथ प्रतिस्थापित किया जाना चाहिए .क्योंकि एंटी-बैक-रेफ़रेंस जैसी कोई चीज नहीं है, और यह किसी भी तरह से मायने नहीं रखता है। पहली स्थिति हमेशा कुछ भी खराब होने से पहले मेल खाएगी।
सिपाही रीड

@SephReed - की जगह [^\1]के साथ .प्रभावी ढंग से करने के लिए इस regex बदल जाएगा ("|').*?\1और फिर इसे से मेल खाएंगे "foo\"में "foo \" bar"। कहा, [^\1]वास्तव में काम करना कठिन है। @ Mathiashansen - आप बेहतर (?!\1).दक्षता के साथ अनिच्छुक और महंगे हैं (इसलिए पूरा रीगेक्स, कुछ दक्षता के साथ, ऐसा होगा (["'])(?:\\.|(?!\1).)*+\1+वैकल्पिक है यदि आपका इंजन इसका समर्थन नहीं करता है।
एडम काटज़

2

एक विकल्प जिसे पहले नहीं छुआ गया है:

  1. स्ट्रिंग को उल्टा करें।
  2. उलटे हुए स्ट्रिंग पर मिलान करें।
  3. मिलान किए गए तारों को फिर से उल्टा करें।

इसमें जोड़ा गया बोनस है जो खुले हुए टैग से बचकर सही मिलान करने में सक्षम है।

कहते हैं कि आपके पास निम्नलिखित स्ट्रिंग थी; String \"this "should" NOT match\" and "this \"should\" match" यहां, \"this "should" NOT match\"मिलान नहीं किया "should"जाना चाहिए और होना चाहिए। उसके शीर्ष पर this \"should\" matchमिलान किया जाना चाहिए और\"should\" होना चाहिए नहीं होना चाहिए।

पहला उदाहरण।

// The input string.
const myString = 'String \\"this "should" NOT match\\" and "this \\"should\\" match"';

// The RegExp.
const regExp = new RegExp(
    // Match close
    '([\'"])(?!(?:[\\\\]{2})*[\\\\](?![\\\\]))' +
    '((?:' +
        // Match escaped close quote
        '(?:\\1(?=(?:[\\\\]{2})*[\\\\](?![\\\\])))|' +
        // Match everything thats not the close quote
        '(?:(?!\\1).)' +
    '){0,})' +
    // Match open
    '(\\1)(?!(?:[\\\\]{2})*[\\\\](?![\\\\]))',
    'g'
);

// Reverse the matched strings.
matches = myString
    // Reverse the string.
    .split('').reverse().join('')
    // '"hctam "\dluohs"\ siht" dna "\hctam TON "dluohs" siht"\ gnirtS'

    // Match the quoted
    .match(regExp)
    // ['"hctam "\dluohs"\ siht"', '"dluohs"']

    // Reverse the matches
    .map(x => x.split('').reverse().join(''))
    // ['"this \"should\" match"', '"should"']

    // Re order the matches
    .reverse();
    // ['"should"', '"this \"should\" match"']

ठीक है, अब RegExp समझाने के लिए। यह regexp आसानी से तीन टुकड़ों में टूट सकता है। निम्नलिखित नुसार:

# Part 1
(['"])         # Match a closing quotation mark " or '
(?!            # As long as it's not followed by
  (?:[\\]{2})* # A pair of escape characters
  [\\]         # and a single escape
  (?![\\])     # As long as that's not followed by an escape
)
# Part 2
((?:          # Match inside the quotes
(?:           # Match option 1:
  \1          # Match the closing quote
  (?=         # As long as it's followed by
    (?:\\\\)* # A pair of escape characters
    \\        # 
    (?![\\])  # As long as that's not followed by an escape
  )           # and a single escape
)|            # OR
(?:           # Match option 2:
  (?!\1).     # Any character that isn't the closing quote
)
)*)           # Match the group 0 or more times
# Part 3
(\1)           # Match an open quotation mark that is the same as the closing one
(?!            # As long as it's not followed by
  (?:[\\]{2})* # A pair of escape characters
  [\\]         # and a single escape
  (?![\\])     # As long as that's not followed by an escape
)

यह शायद छवि के रूप में बहुत स्पष्ट है: जेक्स रेगुलेक्स का उपयोग करके उत्पन्न

गितुब पर छवि (जावास्क्रिप्ट नियमित अभिव्यक्ति विज़ुअलाइज़र।) क्षमा करें, मेरे पास छवियों को शामिल करने के लिए एक उच्च प्रतिष्ठा नहीं है, इसलिए, यह अभी के लिए एक लिंक है।

यहाँ इस अवधारणा का उपयोग करते हुए एक उदाहरण समारोह का एक संकेत दिया गया है जो थोड़ा और अधिक उन्नत है: https://gist.github.com/scagood/bd99371c072d49a4fee29d193252f5fc#file-matchquotes-js


0

एक को याद रखना है कि regexps सब कुछ स्ट्रिंग-वाई के लिए एक चांदी की गोली नहीं है। कुछ सामान एक कर्सर और रैखिक, मैनुअल, मांग के साथ करने के लिए सरल हैं। एक सीएफएल चाल को बहुत ही कम करेगा, लेकिन कई सीएफएल कार्यान्वयन (एफएक्यू) नहीं हैं।


3
यह सच है, लेकिन यह समस्या रीगेक्स की क्षमताओं के भीतर अच्छी तरह से है, और उनमें से कई कार्यान्वयन हैं।
एलन मूर

0

Https://stackoverflow.com/a/10786066/1794894 का अधिक व्यापक संस्करण

/"([^"\\]{50,}(\\.[^"\\]*)*)"|\'[^\'\\]{50,}(\\.[^\'\\]*)*\'|“[^”\\]{50,}(\\.[^“\\]*)*”/   

इस संस्करण में भी शामिल है

  1. न्यूनतम भाव 50 की लंबाई
  2. अतिरिक्त प्रकार के उद्धरण (खुले और बंद )

0

Regexpal पर आस-पास संदेश दिया गया और इस regex के साथ समाप्त हुआ: (मुझसे यह न पूछें कि यह कैसे काम करता है, मैं मुश्किल से भी समझता हूं कि मैंने इसे लिखा है)

"(([^"\\]?(\\\\)?)|(\\")+)+"

0

यदि इसे शुरू से ही खोजा जाए, तो शायद यह काम कर सकता है?

\"((\\\")|[^\\])*\"

0

मुझे उद्धृत फ़ाइलों को पार्स करने में बाधा हो सकती है जो उद्धृत स्ट्रिंग्स को हटाने की कोशिश कर रहे एक समान समस्या का सामना करना पड़ा।

मैंने दो-चरणीय समाधान के साथ समाप्त किया जो किसी भी जटिल रेगेक्स को धड़कता है जो आप के साथ आ सकते हैं:

 line = line.replace("\\\"","\'"); // Replace escaped quotes with something easier to handle
 line = line.replaceAll("\"([^\"]*)\"","\"x\""); // Simple is beautiful

पढ़ने में आसान और शायद अधिक कुशल।


0

यदि आपका IDE IntelliJ Idea है, तो आप इन सभी सिरदर्द को भूल सकते हैं और अपने रेगेक्स को एक स्ट्रिंग चर में स्टोर कर सकते हैं और जैसा कि आप इसे दोहरे-उद्धरण के अंदर कॉपी-पेस्ट करते हैं, यह स्वचालित रूप से एक regex स्वीकार्य प्रारूप में बदल जाएगा।

जावा में उदाहरण:

String s = "\"en_usa\":[^\\,\\}]+";

अब आप अपने चर में या कहीं भी इस चर का उपयोग कर सकते हैं।

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