2009-08-11 14 views
6

मैं परीक्षण करना चाहता हूं कि एक रेगेक्स एक विशिष्ट इंडेक्स पर स्ट्रिंग के हिस्से से मेल खाएगा (और केवल उस विशिष्ट इंडेक्स से शुरू हो रहा है)। उदाहरण के लिए, स्ट्रिंग को "एक दो 3 4 पांच" दिया गया, मैं यह जानना चाहता हूं कि, सूचकांक 8 पर, नियमित अभिव्यक्ति [0-9] + "3" से मेल खाती है। RegularExpression.IsMatch और मैच दोनों एक प्रारंभिक सूचकांक लेते हैं, हालांकि वे दोनों आवश्यक होने पर एक मैच के लिए पूरे स्ट्रिंग को खोजेंगे।सी # नियमित अभिव्यक्ति मैच?

string text="one two 3 4 five"; 
Regex num=new Regex("[0-9]+"); 

//unfortunately num.IsMatch(text,0) also finds a match and returns true 
Console.WriteLine("{0} {1}",num.IsMatch(text, 8),num.IsMatch(text,0)); 
जाहिर

, अगर जिसके परिणामस्वरूप मैच सूचकांक मैं में दिलचस्पी है पर शुरू होता है मैं जांच कर सकता है, लेकिन मैं इस बड़े तारों पर समय की एक बड़ी संख्या में कर रही होगी, तो मैं समय बर्बाद करने के लिए खोज नहीं करना चाहते बाद में स्ट्रिंग में मैचों के लिए। साथ ही, मैं पहले से नहीं जानूंगा कि नियमित अभिव्यक्ति मैं वास्तव में स्ट्रिंग के खिलाफ परीक्षण करूँगा।

मैं नहीं करना चाहता:

  1. क्योंकि मेरे स्थिति में कुछ सीमा खाली स्थान के तरह पर स्ट्रिंग विभाजित मैं अग्रिम में पता नहीं होगा क्या एक उपयुक्त सीमा होगा
  2. करने के लिए है किसी भी तरह से में इनपुट स्ट्रिंग को संशोधित
  3. एक चटाई के लिए स्ट्रिंग के बाकी खोज (सूचकांक 8 पर सबस्ट्रिंग हो रही है और फिर regex में उपयोग कर ^) की तरह ch या कुछ भी करें जो बड़ी स्ट्रिंग के विरुद्ध बड़ी संख्या में परीक्षणों के लिए प्रदर्शन नहीं करेगा।

मैं एक मनमानी उपयोगकर्ता द्वारा प्रदान किए गए व्याकरणिक उपयोगकर्ता द्वारा उपयोग किए जाने वाले संभावित बड़े उपयोगकर्ता द्वारा समर्थित शरीर को पार्स करना चाहता हूं। व्याकरण को बीएनएफ या पीईजी में सिंटैक्स की तरह परिभाषित किया जाएगा, और टर्मिनलों या तो स्ट्रिंग अक्षर या नियमित अभिव्यक्ति होगी। इस प्रकार मुझे यह जांचने की आवश्यकता होगी कि स्ट्रिंग का अगला भाग ग्रामर द्वारा संचालित संभावित टर्मिनल से मेल खाता है या नहीं।

+1

क्या आप समझा सकते हैं कि आप व्यापक अर्थ में क्या करने की कोशिश कर रहे हैं? जो आप नहीं करना चाहते हैं उस पर आपके प्रतिबंध भ्रमित हैं। –

+0

मैंने जो कुछ भी कर रहा हूं उसका एक संक्षिप्त विवरण जोड़ा। इसके अलावा, आवश्यकताओं को वास्तव में उबालते हैं: मैं कुछ भी धीमा नहीं करना चाहता हूं और मुझे गहराई से ज्ञान नहीं है कि मैं आगे बढ़ने की कोशिश कर रहा हूं। – Rngbus

उत्तर

11

\G (जिसका अर्थ है "अंतिम मिलान की शुरुआत" से शुरू होने वाली नियमित अभिव्यक्ति का उपयोग करके Regex.IsMatch(string, int) का उपयोग करने के बारे में कैसे?

प्रतीत होता है कि काम करने के लिए:

using System; 
using System.Text.RegularExpressions; 

class Test 
{ 
    static void Main() 
    { 
     string text="one two 3 4 five"; 
     Regex num=new Regex(@"\G[0-9]+"); 

     Console.WriteLine("{0} {1}", 
          num.IsMatch(text, 8), // True 
          num.IsMatch(text, 0)); // False 
    } 
} 
+0

दिलचस्प, अगर अंतिम मैच स्थिति को कलात्मक रूप से सेट करने का कोई तरीका है तो यह काम कर सकता है। अन्यथा मुझे नहीं लगता कि इससे मदद मिलेगी क्योंकि मैं अलग-अलग नियमित अभिव्यक्तियों और विभिन्न स्थानों के बीच कूद रहा हूं। – Rngbus

+0

मुझे यह कोशिश करने का मौका मिला और ऐसा लगता है कि मैं वही कर रहा हूं जो मैं चाहता हूं। यह अंतिम मैच वास्तव में कहां था, इस पर ध्यान दिए बिना पारित प्रारंभ सूचकांक "अंतिम मैच की शुरुआत" के रूप में व्यवहार करता है। बहुत बहुत धन्यवाद! – Rngbus

+2

और इस समस्या में किसी और के लिए थोड़ी सी जानकारी जोड़ने के लिए, http://www.regular-expressions.info/continue.html \ G एंकर का वर्णन करता है। ऐसा लगता है कि कार्यान्वयन के आधार पर या तो "अंतिम मैच की शुरुआत" या "मैच प्रयास की शुरुआत" का अर्थ है। कुछ कार्यान्वयन में यह शायद इस समस्या को हल नहीं करेगा, लेकिन ऐसा लगता है कि यह सी # में "मिलान प्रयास की शुरुआत" प्रतीत होता है और किसी विशिष्ट स्थान पर मिलान के लिए अच्छी तरह से काम करता है। – Rngbus

2

आप केवल पाठ की सबस्ट्रिंग खोज करने के लिए, regex से पहले कि सबस्ट्रिंग हड़पने चाहते हैं।

myRegex.Match(myString.Substring(8, 10)); 
+2

प्रश्न में बिंदु 2 देखें। –

+0

ऐसा नहीं लगता इनपुट इनपुट स्ट्रिंग को संशोधित करता है, इसलिए +1। यदि बिंदु 2 इनपुट स्ट्रिंग को बदलने के बारे में नहीं है, तो इसे संपादित करने की आवश्यकता है। – ojrac

+1

ठीक है, यह नियमित अभिव्यक्ति * में इनपुट * को संशोधित कर रहा है। "बड़े तारों पर यह बड़ी संख्या में ऐसा करने" को देखते हुए मैंने सोचा नहीं था कि एक सबस्ट्रिंग एक आदर्श समाधान था। –

1

मुझे यकीन है कि मैं पूरी तरह से सवाल समझ में नहीं हूँ, लेकिन यह है कि आप केवल नियमित अभिव्यक्ति, उदा की स्थिति हिस्सा बना सकते हैं मुझे लगता है

^.{8}[\d] 

जो स्ट्रिंग और अंक की शुरुआत के बीच 8 वर्ण होने पर मेल खाएगा।

+1

यह आदर्श नहीं है, क्योंकि इसमें प्रत्येक स्थिति के लिए रेगेक्स को संशोधित करना शामिल होगा जिसमें मैं परीक्षण करना चाहता हूं। यह रेगेक्स पर निर्भर करता है जो^^ 8} को ऑप्टिमाइज़ करने के लिए पर्याप्त स्मार्ट है। तुरंत 8 स्थिति में कूदता है। – Rngbus

0

आप स्ट्रिंग के लिए इस स्ट्रिंग की स्कैनिंग सीमित हो जाएगी आप की जाँच में एक संभावित मैच की अधिकतम लंबाई पता है।

आप केवल संख्या के लिए जाँच कर रहे हैं, तो यह शायद अगर आप मनमाने ढंग से भाव के लिए जाँच की तुलना में आसान है। रेगेक्स की प्रकृति एक मैच खोजने के लिए अंत तक स्कैन करना है। यदि आप स्कैनिंग को रोकना चाहते हैं तो आपको लंबाई शामिल करने की आवश्यकता है, या रेगेक्स के अलावा कुछ और उपयोग करना है।

string text = "one two 3 4 five"; 
Regex num = new Regex("[0-9]+"); 
int indexToCheck = 8; 
int maxMatchLength = ...; 
Match m = num.Match(text, indexToCheck, maxMatchLength); 

आप क्या प्रकार के भाव के तार के खिलाफ चलाया जा सकता है के बारे में कुछ पता है, और स्कैनिंग जाएगा पूरी स्ट्रिंग एक ओवरहेड में बहुत कुछ हो?

num.Match मौजूद होने पर पहली हिट वापस कर देगा, और फिर स्कैनिंग रोकें। यदि आप अधिक मिलान चाहते हैं तो आप मैचों की स्कैनिंग जारी रखने के लिए m.NextMatch() को कॉल करेंगे।

+0

दुर्भाग्य से मुझे नहीं पता कि नियमित अभिव्यक्ति पहले से क्या होगी और बाकी की तुलना में अधिकतम लंबाई प्रदान नहीं कर सकती स्ट्रिंग का – Rngbus

+0

व्हाइटस्पेस के आधार पर खोजने की अभिव्यक्ति में भिन्नता हो सकती है उदा। नई लाइनें और इंडेंट अनुच्छेद शुरू होता है, या जो भी हो। – ProfK

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