2009-06-12 15 views
5

.NET regex क्यों नहीं है लाइन वर्ण के अंत के रूप में \ n?.NET की रेगेक्स क्लास और न्यूलाइन

नमूना कोड:

string[] words = new string[] { "ab1", "ab2\n", "ab3\n\n", "ab4\r", "ab5\r\n", "ab6\n\r" }; 
Regex regex = new Regex("^[a-z0-9]+$"); 
foreach (var word in words) 
{ 
    Console.WriteLine("{0} - {1}", word, regex.IsMatch(word)); 
} 

और यह प्रतिक्रिया मैं है:

ab1 - True 
ab2 
- True 
ab3 

- False 
- False 
ab5 
- False 
ab6 
- False 

क्यों regex मैच ab2\n?

अद्यतन: मुझे नहीं लगता कि Multiline एक अच्छा समाधान है, कि है, मैं लॉगिन केवल निर्दिष्ट वर्णों का मिलान करने मान्य करने के लिए चाहते हैं, और यह एक पंक्ति होना चाहिए। यदि मैं मल्टीलाइन विकल्प ab1, ab2, ab3 और ab6 के लिए कन्स्ट्रक्टर बदलता हूं तो अभिव्यक्ति से मेल खाता है, ab4 और ab5 इसे मेल नहीं खाते हैं।

+0

क्यों ab4 उत्पादन में दिखाई नहीं देता? –

+0

मुझे लगता है कि यह अकेले \ r की वजह से है - यह कंसोल – empi

उत्तर

9

यदि स्ट्रिंग लाइन ब्रेक के साथ समाप्त होती है तो RegexOptions.Multiline काम नहीं करेगा। $ केवल अंतिम लाइन ब्रेक को अनदेखा कर देगा क्योंकि इसके बाद कुछ भी नहीं है।

आप स्ट्रिंग के अंत तक मेल खाते हैं और अनदेखी करने के लिए चाहते हैं, तो किसी भी पंक्ति विराम \z

Regex regex = new Regex(@"^[a-z0-9]+\z", RegexOptions.Multiline); 

यह दोनों MutliLine और Singleline, कि कोई फर्क नहीं पड़ता के लिए है का उपयोग करें।

+0

धुंधला, आप सही हैं। मैं \ Z \ z metacharacters (+1) –

+0

के बारे में भूल गया यह काम करता है, लेकिन क्या आप जानते हैं कि यह दृष्टिकोण किसी अन्य समस्या का कारण बन सकता है? \ Z और $ के बीच क्या अंतर है? – empi

+0

\ z केवल नई स्ट्रिन –

1
RegexOptions से

:

बहुपंक्ति मोड।^और $ का अर्थ बदलता है ताकि वे किसी भी पंक्ति के क्रमशः शुरुआत और अंत में मेल खाते हों, न केवल संपूर्ण स्ट्रिंग की शुरुआत और अंत।

तो बुनियादी तौर पर अगर आप पारित Regex निर्माता के लिए एक RegexOptions.Multiline आपको लगता है कि उदाहरण के निर्देश देते रहे हैं न्यू लाइन पात्रों के लिए अंतिम $ एक मैच के रूप के इलाज के लिए - नहीं बस स्वयं स्ट्रिंग के अंत।

+0

से सटीक आउटपुट है, जहां तक ​​मैं इसे समझता हूं, मैं स्ट्रिंग में दिखाई देने वाले सभी वर्ण निर्दिष्ट कर रहा हूं और ये वर्ण वर्णों के अंतर्गत वर्ण हैं [a-z0-9 ]। मैं \ n स्ट्रिंग में प्रकट होने की इजाजत नहीं दे रहा हूं, हालांकि रेगेक्स अभी भी स्ट्रिंग से मेल खाता है \ n। मुझे समझ में नहीं आता कि मल्टीलाइन को इसके साथ क्या करना है। – empi

0

अंतर्निहित विंडोज/लिनक्स लाइन अंतर को समाप्त कर सकता है। लेकिन यह अभी भी अजीब बात है कि \n\n इस तरह से झूठा हो जाता है ... क्या आपने RegexOptions.Multiline ध्वज सेट के साथ प्रयास किया था?

0

बस स्माज़ी जवाब के लिए अधिक जानकारी देने के लिए। यह एक निकास: जन गोवार्ट्स और स्टीवन लेविथन द्वारा नियमित अभिव्यक्ति कुकबुक। कॉपीराइट 2009 जनवरी Goyvaerts और स्टीवन Levithan, 978-0-596-2068-7

के बीच अंतर <\ जेड> और <\ z> खेलने में जब अपने विषय पाठ में पिछले चरित्र है आता है एक लाइन ब्रेक। उस स्थिति में, <\ Z> विषय टेक्स्ट के अंत में अंतिम लाइन ब्रेक के बाद, के रूप में अच्छी तरह से उस पंक्ति से पहले ब्रेक के बाद मेल कर सकता है। लाभ यह है कि आप के लिए बिना किसी विषय लाइन ब्रेक को अपने विषय टेक्स्ट के अंत में बंद करने के बारे में चिंता किए बिना खोज सकते हैं। लाइन द्वारा फ़ाइल लाइन पढ़ने पर, कुछ टूल लाइन के अंत में ब्रेक लाइन को शामिल करते हैं, जबकि अन्य नहीं करते हैं; <\ Z> मुखौटा यह अंतर। <\ Z> केवल पर विषय टेक्स्ट के बहुत अंत से मेल खाता है, इसलिए टेक्स्ट की मिलान नहीं करेगा यदि पिछली रेखा ब्रेक निम्नानुसार है। एंकर <$> <\ Z> के समतुल्य है, जब तक आप लाइन ब्रेक "विकल्प पर"^और $ मिलान चालू नहीं करते हैं। यह विकल्प रूबी को छोड़कर सभी regex स्वादों के लिए डिफ़ॉल्ट है। रूबी पर एक विकल्प प्रदान नहीं करता है इस विकल्प को बंद करें। विषय टेक्स्ट के साथ-साथ अंतिम लाइन ब्रेक से पहले, यदि कोई हो, तो <\ Z>, <$> मैचों की तरह।

बेशक, मुझे बिना धुंधले जवाब के यह मिल गया होगा।

10

.NET regex इंजन \n का अंत-अंतराल के रूप में व्यवहार करता है। और यह एक समस्या है यदि आपकी स्ट्रिंग में Windows-style \r\n लाइन ब्रेक हैं। RegexOptions.Multiline $\r और \n के बीच \r से पहले के मुकाबले चालू हो गया।

$ स्ट्रिंग के बहुत ही अंत में \z की तरह मेल खाता है। अंतर यह है कि \z केवल स्ट्रिंग के बहुत ही अंत में मेल खा सकता है, जबकि $ पीछे की ओर \n से पहले भी मेल खाता है। RegexOptions.Multiline का उपयोग करते समय, $ किसी भी \n से पहले मेल खाता है।

यदि आपको लाइन ब्रेक के साथ परेशानी हो रही है, तो सभी \r को बदलने के लिए खोज और प्रतिस्थापन के लिए पहली बार एक चाल है, यह सुनिश्चित करने के लिए कि आपकी सभी लाइनें केवल \n के साथ समाप्त हों।

+2

की परवाह किए बिना स्ट्रिंग के अंत से मेल खाता है, मैं "\ r \ n" को "\ n" के साथ बदलना पसंद करता हूं, बस कुछ पागल दस्तावेज़ों में केवल कुछ ही "\ r" स्वयं लाइन अंत के रूप में होता है। – Jimmy

1

उपयोग regex विकल्प, System.Text.RegularExpressions.RegexOptions:

string[] words = new string[] { "ab1", "ab2\n", "ab3\n\n", "ab4\r", "ab5\r\n", "ab6\n\r" }; 
Regex regex = new Regex("^[a-z0-9]+$"); 
foreach (var word in words) 
{ 
    Console.WriteLine("{0} - {1}", word, 
     regex.IsMatch(word,"^[a-z0-9]+$", 
      System.Text.RegularExpressions.RegexOptions.Singleline | 
      System.Text.RegularExpressions.RegexOptions.IgnoreCase | 
      System.Text.RegularExpressions.RegexOptions.IgnorePatternWhitespace)); 
} 
संबंधित मुद्दे