2011-02-13 24 views
6

पर मिलान रेगेक्स मैं यह जांचना चाहता हूं कि एक निश्चित पैटर्न (उदाहरण के लिए एक डबल उद्धृत स्ट्रिंग) सटीक स्थिति पर मेल खाता है या नहीं।सटीक ऑफ़सेट

उदाहरण

string text = "aaabbb"; 
Regex regex = new Regex("b+"); 
// Now match regex at exactly char 3 (offset) of text 

मैं अगर वास्तव में चार 3.
पर regex मैचों मैं Regex.Match Method (String, Int32) पर एक नज़र था जांच करना चाहते हैं, लेकिन यह व्यवहार न करे कि मैं उम्मीद।

public void RegexTest2() 
{ 
    Match m; 
    string text = "aaabbb"; 
    int offset = 3; 

    m = new Regex("^a+").Match(text, 0); // lets do a sanity check first 
    Assert.AreEqual(true, m.Success); 
    Assert.AreEqual("aaa", m.Value); // works as expected 

    m = new Regex("^b+").Match(text, offset); 
    Assert.AreEqual(false, m.Success); // this is quite strange... 

    m = new Regex("^.{"+offset+"}(b+)").Match(text); // works, but is not very 'nice' 
    Assert.AreEqual(true, m.Success); 
    Assert.AreEqual("bbb", m.Groups[1].Value); 

    m = new Regex("^b+").Match(text.Substring(offset)); // works too, but 
    Assert.AreEqual(true, m.Success); 
    Assert.AreEqual("bbb", m.Value); 
} 

वास्तव में मुझे विश्वास है कि new Regex("^.", 1).Match(myString)कुछ भी मेल खाते हैं कभी नहीं होगा शुरू कर:
तो मैं कुछ परीक्षण और कुछ समाधान किया।

कोई सुझाव?

संपादित करें:

मैं एक काम कर समाधान (वैकल्पिक हल) मिला है। तो मेरा सवाल गति और एक अच्छा कार्यान्वयन के बारे में सब कुछ है।

उत्तर

8

क्या आपने कोशिश की है कि docs क्या कहता है?

तो यह स्ट्रिंग में एक विशेष चरित्र की स्थिति और में शुरू होता है आप एक मैच सीमित करना चाहते हैं कि नियमित अभिव्यक्ति इंजन एक मैच के लिए स्ट्रिंग के शेष स्कैन नहीं करता है, नियमित रूप से लंगर अभिव्यक्ति एक \ G ( बाएं से दाएं पैटर्न के लिए बायीं तरफ, या दाएं से बाएं पैटर्न के लिए दाएं पर)। यह मैच को प्रतिबंधित करता है, इसलिए इसे प्रारंभ में प्रारंभ करना होगा।

यानी।एक \G साथ ^ बदल देते हैं:

m = new Regex(@"\Gb+").Match(text, offset); 
Assert.AreEqual(true, m.Success); // should now work 
+0

बहुत अच्छा विचार! –

+0

मुझे 8 सेकंड तक मारो, मुझे पुष्टि करने के लिए बहुत लंबा लगा: 'पी'। '\ G' यहां सही है, लेकिन मैं उसी 'Regex' ऑब्जेक्ट का उपयोग करने के बारे में एक चेतावनी जोड़ूंगा, मान लीजिए कि ओपी हर बार एक नया निर्माण नहीं करेगा। मुझे पूरा यकीन नहीं है कि यह कैसे व्यवहार करेगा, लेकिन ऑफसेट के साथ भी यह अंतिम स्थिति याद रख सकता है। यह जांचने लायक है कि एक। (फिर से, मुझे यकीन नहीं है) – Kobi

+0

@ कोबी - मुझे संदेह है कि यह मामला केवल तभी हो सकता है जब आप m.MatchNext() का उपयोग करते हैं, न कि यदि आप उसी Regex ऑब्जेक्ट पर फिर से मिलान() को कॉल करते हैं। – CAFxX

0

आप अपने regex के लिए एक सकारात्मक lookbehind दावा ((?<=...)) जोड़ सकते हैं:

Regex regex = new Regex("(?<=\A.{3})b+"); 

यह सुनिश्चित करता है वहाँ वास्तव में कर रहे हैं स्ट्रिंग (\A) की शुरुआत के बाद तीन अक्षरों (.{3}) है कि और की शुरुआत से पहले रेगेक्स आप \A के बजाय ^ का भी उपयोग कर सकते हैं, लेकिन चूंकि पूर्व का अर्थ भी हो सकता है (कुछ परिस्थितियों में) "रेखा की शुरुआत में मिलान करें", बाद वाला थोड़ा और स्पष्ट है।

आपको RegexOptions.Singleline का उपयोग कर रेगेक्स को संकलित करने की आवश्यकता हो सकती है ताकि डॉट को न्यूलाइन अक्षरों से मेल खाने की अनुमति मिल सके।

वैसे,

m = new Regex("^b+").Match(text, 3); 

काम नहीं करता है, क्योंकि पहली b से पहले लाइन की शुरुआत और स्थिति पर ^ मैचों जाहिर है, लाइन के शुरू में नहीं है।

+0

क्षमा करें, मैं उल्लेख करना भूल गया, ऑफसेट '3' का एक चर है। अगर मैं हर कॉल के लिए एक नया रेगेक्स बनाया तो क्या नाटकीय रूप से प्रदर्शन कम नहीं होगा? –

+0

ठीक है, उस स्थिति में, मैं आपकी स्ट्रिंग के प्रासंगिक भाग को प्राप्त करने के लिए 'सबस्ट्रिंग' के उपयोग की वकालत करता हूं और फिर शेष पर रेगेक्स के क्रोध को मुक्त करता हूं। –

+1

क्या धीमा नहीं है यदि स्ट्रिंग का मिलान किया जाए तो _very long_ है? –

1

आप उम्मीद Match(text, offset)शुरू करने के लिए की खोज स्ट्रिंग का मूल्यांकन यह ऑफसेट पर शुरू किया गया था के रूप में यदि। ऐसा नहीं है। ^ वास्तव में 0 ऑफसेट करने के लिए मूल्यांकन करेगा, offset नहीं!

तो overload of Match का उपयोग करें कि ^offset करने का मूल्यांकन करेंगे:

m = new Regex("^bbb$").Match(text, offset, text.Length-offset); 

एक और विकल्प का उपयोग किया जाएगा, लेकिन यह ऊपर एक की तुलना में धीमी:

m = new Regex("^.{"+offset+"}bbb$").Match(text); 

या इस (पहली विधि सबसे तेज़ है):

m = new Regex(@"\Gbbb$").Match(text, offset); 
संबंधित मुद्दे