2011-09-07 10 views
6

शब्द शामिल नहीं है और मैं ऐसा नहीं कर सका। मैं पूरी तरह से नोब नहीं हूँ।Regex - दो शब्दों के बीच स्ट्रिंग प्राप्त करें जिसमें

मुझे स्टार्ट और ईएनडी द्वारा सीमित पाठ प्राप्त करने की आवश्यकता है जिसमें स्टार्ट नहीं है। मूल रूप से मुझे उन्नत सामग्री का उपयोग किये बिना पूरे शब्द को अस्वीकार करने का कोई तरीका नहीं मिल रहा है।

उदाहरण स्ट्रिंग:

abcSTARTabcSTARTabcENDabc

अपेक्षित परिणाम:

STARTabcEND

अच्छा नहीं:

0,123,

STARTabcSTARTabcEND

मैं पिछड़े खोज सामान का उपयोग नहीं कर सकते हैं। मैं यहां अपने रेगेक्स का परीक्षण कर रहा हूं: www.regextester.com

किसी भी सलाह के लिए धन्यवाद।

+0

क्या होगा यदि टेक्स्ट 'abcSTARTabcENDabcSTARTabcENDabc' है? क्या आप दोनों मैच चाहते हैं? –

+0

उस बारे में नहीं सोचा था ... वैसे भी, यदि आवश्यक हो तो मुझे दूसरा मैच मिल सकता है। – rrr

+0

एक एकल regex में ऐसा करने के लिए बेहतर है। मैंने एक जवाब जोड़ा है। –

उत्तर

4

वास्तव में पैदल यात्री समाधान START(([^S]|S*S[^ST]|ST[^A]|STA[^R]|STAR[^T])*(S(T(AR?)?)?)?)END होगा। आधुनिक रेगेक्स स्वादों में नकारात्मक धारणाएं होती हैं जो यह अधिक सुंदर ढंग से करती हैं, लेकिन मैं "पिछली खोज" के बारे में आपकी टिप्पणी की व्याख्या करता हूं, शायद यह मतलब है कि आप इस सुविधा का उपयोग नहीं करना चाहते हैं या नहीं।

अद्यतन: बस पूर्णता के लिए, ध्यान दें कि उपरोक्त अंतराल के संबंध में उपरोक्त लालची है। केवल सबसे कम संभव स्ट्रिंग को कैप्चर करने के लिए, अंतिम डिलीमीटर - START(([^ES]|E*E[^ENS]|EN[^DS]|S*S[^STE]|ST[^AE]|STA[^RE]|STAR[^TE])*(S(T(AR?)?)?|EN?)?)END को कवर करने के लिए अस्वीकृति का विस्तार करें। हालांकि, अधिकांश संस्कृतियों में यातना सीमा से अधिक होने का जोखिम है।

बग का समाधान: इस उत्तर के पिछले संस्करण, एक बग था कि SSTART में मैच (दूसरा S[^T] से मेल खाएंगे, आदि) का हिस्सा हो सकता है।मैं [^ST] में S के अलावा द्वारा लेकिन यह तय की और से पहले गैर वैकल्पिक SS* जोड़ने S अन्यथा की मनमानी repetitions के लिए अनुमति देने के लिए।

+0

अच्छा समाधान (यदि कोई लुकहेड संभव नहीं है) +1 – stema

+0

+1 कोई दिखने के साथ कैसे दिखाना है – shelleybutterfly

+0

यही वह है जिसे मैं ढूंढ रहा था, धन्यवाद। वास्तव में ... पैदल यात्री :) लेकिन यह काम करता है। मैं उम्मीद कर रहा था कि एक आसान तरीका हो सकता है कि मैं याद कर रहा हूं। पहले वापस पोस्ट न करने के लिए खेद है। – rrr

10

इस

START(?!.*START).*?END 

देखें कि यह here online on Regexr

(?!.*START) एक नकारात्मक अग्रदर्शी है की कोशिश करो। यह सुनिश्चित करता है कि "START" शब्द

.*? अगले "END" तक सभी वर्णों का एक गैर लालची मैच नहीं है। इसकी जरूरत है, क्योंकि नकारात्मक अग्रदर्शी बस आगे दिख रही है और कुछ भी (शून्य लंबाई अभिकथन) पर कब्जा नहीं

अद्यतन:

मैंने सोचा कि थोड़ा अधिक, समाधान ऊपर पहले "END" जब तक मिलान किया जाता है। यदि यह चाहते थे नहीं है (क्योंकि आप सामग्री से स्टार्ट छोड़कर कर रहे हैं) तो लालची संस्करण

START(?!.*START).*END 

यह पिछले "END" तक का मिलान करेगा का उपयोग करें।

+0

+1 मुझे यहां 1 9 सेकेंड तक मारो। :) –

+0

+1 अच्छी तरह से किया गया। –

+0

सभी ऑपरेटरों के सरल स्पष्टीकरण के साथ अच्छे उत्तर के लिए +1 – shelleybutterfly

0

[संपादित करें: मैं कैप्चर समूहों के बारे में जानकारी है, लेकिन मुख्य समाधान मैं सही नहीं था दे दी है के लिए इस पोस्ट को छोड़ दिया है। (?:START)((?:[^S]|S[^T]|ST[^A]|STA[^R]|STAR[^T])*)(?:END) के रूप में टिप्पणी कार्य नहीं करेगा में बताया; मैं भूल गया था कि ध्यान नहीं दिया पात्रों गिरा नहीं किया जा सका है और इस तरह आप कुछ इस तरह के रूप ... |STA(?![^R])| अभी भी उस चरित्र अंत का हिस्सा बनने के लिए अनुमति देते हैं करने की आवश्यकता होगी, इस प्रकार इस तरह के STARTSTAEND के रूप में कुछ पर विफल रहने; तो यह स्पष्ट रूप से एक बेहतर विकल्प है; निम्नलिखित कैप्चर समूहों का उपयोग करने के लिए उचित तरीका दिखाना चाहिए ...]

कैप्चर समूहों के साथ 'शून्य-चौड़ाई नकारात्मक लुकहेड' ऑपरेटर "?!" का उपयोग करके दिया गया जवाब है: (?:START)((?!.*START).*)(?:END) जो आंतरिक पाठ को कैप्चर करता है प्रतिस्थापन के लिए $ 1 का उपयोग कर। यदि आप स्टार्ट और ईएनडी टैग कैप्चर करना चाहते हैं तो आप (START)((?!.*START).*)(END) कर सकते हैं जो () एस या ?: एस जोड़कर/हटाकर $ 1 = START $ 2 = टेक्स्ट और $ 3 = END या कई अन्य क्रमपरिवर्तन देता है।

इस तरह यदि आप इसे खोज और प्रतिस्थापित करने के लिए उपयोग कर रहे हैं, तो आप ऐसा कर सकते हैं, जैसे कि $ $ 1FINISH। इसलिए, यदि आप के साथ शुरू किया:

abcSTARTdefSTARTghiENDjkl

आप कैप्चर समूह 1 के रूप में ghi प्राप्त होता है, और शुरू $ 1FINISH साथ की जगह आप देना होगा निम्नलिखित:

abcSTARTdefBEGINghiFINISHjkl

जो आप की अनुमति होगी सही ढंग से जोड़े जाने पर ही अपना स्टार्ट/ईएनडी टोकन बदलना।

प्रत्येक (x) एक समूह है, लेकिन मैंने मध्य में छोड़कर प्रत्येक के लिए (?:x) रखा है जो इसे गैर-कैप्चरिंग समूह के रूप में चिह्नित करता है; ?: के बिना मैंने छोड़ा केवल एक ही था; हालांकि, आप BEGIN/END टोकन को भी अनुमानित रूप से कैप्चर कर सकते हैं यदि आप उन्हें चारों ओर ले जाना चाहते हैं या आप क्या हैं।

जावा रेगेक्स पर पूर्ण विवरण के लिए Java regex documentation देखें।

+0

आप स्टार्टस्टैंड पैटर्न पर असफल हो जाते हैं। – tripleee

+0

@ ट्रिपली श्वास, हां, वास्तव में और मुझे उन पात्रों को अनदेखा करने की आवश्यकता होगी? जो कि पूरे उद्देश्य को हरा देता है। यह इंगित करने के लिए धन्यवाद। – shelleybutterfly

4
START(?:(?!START).)*END 

START...END जोड़े के किसी भी संख्या के साथ काम करेगा। अजगर में प्रदर्शित करने के लिए:

>>> import re 
>>> a = "abcSTARTdefENDghiSTARTjlkENDopqSTARTrstSTARTuvwENDxyz" 
>>> re.findall(r"START(?:(?!START).)*END", a) 
['STARTdefEND', 'STARTjlkEND', 'STARTuvwEND'] 

आप केवल START और END के बीच सामग्री के लिए देखभाल करते हैं, तो इसका उपयोग करें:

(?<=START)(?:(?!START).)*(?=END) 

इसे यहाँ देखें:

>>> re.findall(r"(?<=START)(?:(?!START).)*(?=END)", a) 
['def', 'jlk', 'uvw'] 
+0

यूप, यह यह करेगा। +1 (हालांकि आप 's' dot-matches-all flag का उल्लेख/उपयोग करना चाह सकते हैं।) – ridgerunner

2

मैं एक संभव सुझाव है मई टिम Pietzcker के समाधान पर सुधार? मुझे ऐसा लगता है कि START(?:(?!START).)*?END केवल START को पकड़ने के लिए बेहतर है, इसके बाद END के बाद START या END के बीच में। मैं .NET का उपयोग कर रहा हूं और टिम का समाधान START END END जैसे कुछ भी मेल खाता है। कम से कम मेरे व्यक्तिगत मामले में यह नहीं चाहता था।

संबंधित मुद्दे