2010-08-20 14 views
5

.NET में, regex कैप्चर का आयोजन नहीं कर रहा है जैसा कि मैं उम्मीद करता हूं। (मैं इसे एक बग नहीं कहूंगा, क्योंकि स्पष्ट रूप से किसी ने इसका इरादा किया था। हालांकि, यह नहीं है कि मैं इसे कैसे काम करने की उम्मीद करता हूं और न ही मुझे यह उपयोगी लगता है।).NET regex कैप्चर अपेक्षित क्रम में नहीं

यह रेगेक्स नुस्खा सामग्री के लिए है (खातिर सरलीकृत उदाहरण के):

(?<measurement>   # begin group 
    \s*      # optional beginning space or group separator 
    (
    (?<integer>\d+)|  # integer 
    (
     (?<numtor>\d+)  # numerator 
    /
     (?<dentor>[1-9]\d*) # denominator. 0 not allowed 
    ) 
) 
    \s(?<unit>[a-zA-Z]+) 
)+      # end group. can have multiple 

मेरे स्ट्रिंग: 3 tbsp 1/2 tsp

परिणामस्वरूप समूहों और कब्जा:

[माप] [0] = 3 चम्मच
[माप] [] = 1/2 चम्मच
[पूर्णांक] [0] = 3
[numtor] [] = 1
[dentor] [] = 2
[इकाई] [0] = चम्मच
[इकाई] [] = चम्मच

सूचना कैसे भले ही 1/2 tsp 2 कैद में है, यह भागों [0] में हैं क्योंकि इन धब्बों previousl थे वाई अप्रयुक्त

क्या सभी हिस्सों को फिर से रेगेक्स के माध्यम से प्रत्येक समूह को फिर से चलाने के बिना अनुमानित उपयोगी अनुक्रमणिका प्राप्त करने का कोई तरीका है?

उत्तर

1

वहाँ किसी भी तरह से भागों के सभी प्राप्त करने के लिए है प्रत्येक समूह को फिर से रेगेक्स के माध्यम से फिर से चलाने के बिना पूर्वानुमानित उपयोगी अनुक्रमणिका प्राप्त करने के लिए?

कैप्चर के साथ नहीं।और तुम वैसे भी कई मैचों प्रदर्शन करने के लिए जा रहे हैं, मैं सुझाव है कि आप + हटाने और अलग माप के प्रत्येक घटक से मेल खाते हैं तो तरह,:

string s = @"3 tbsp 1/2 tsp"; 

    Regex r = new Regex(@"\G\s* # anchor to end of previous match 
    (?<measurement>   # begin group 
     (
     (?<integer>\d+)  # integer 
     | 
     (
      (?<numtor>\d+)  # numerator 
     /
      (?<dentor>[1-9]\d*) # denominator. 0 not allowed 
     ) 
    ) 
     \s+(?<unit>[a-zA-Z]+) 
    )       # end group. 
    ", RegexOptions.IgnorePatternWhitespace | RegexOptions.ExplicitCapture); 

    foreach (Match m in r.Matches(s)) 
    { 
    for (int i = 1; i < m.Groups.Count; i++) 
    { 
     Group g = m.Groups[i]; 
     if (g.Success) 
     { 
     Console.WriteLine("[{0}] = {1}", r.GroupNameFromNumber(i), g.Value); 
     } 
    } 
    Console.WriteLine(""); 
    } 

उत्पादन:

[measurement] = 3 tbsp 
[integer] = 3 
[unit] = tbsp 

[measurement] = 1/2 tsp 
[numtor] = 1 
[dentor] = 2 
[unit] = tsp 

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

1

ऐसा लगता है कि आपको एक समय में एक माप से मिलान करने के लिए इनपुट के माध्यम से लूप की आवश्यकता होती है। तब उस माप के लिए लूप पुनरावृत्ति के दौरान, उस माप के हिस्सों में आप अनुमानित पहुंच प्राप्त करेंगे।

-1

इस पर एक नज़र होने .... यहाँ कुछ सुझाव है कि regexp

(?<measurement>   # begin group 
    \s*      # optional beginning space or group separator 
    (
    (?<integer>\d+)\.?| # integer 
    (
     (?<numtor>\d+)  # numerator 
    /
     (?<dentor>[1-9]\d*) # denominator. 0 not allowed 
    ) 
) 
    \s(?<unit>[a-zA-Z]+) 
)+      # end group. can have multiple 
  • regex शुरू में एक अंतरिक्ष उम्मीद कर रही है बेहतर बनाने में मदद कर सकते हैं है .... माप टैग के बाद ....
  • ..
  • (?<integer>\d+) मैं \. के बजाय \s? कोशिश खाली स्थान के कब्जा करने के लिए है कि के रूप में पूर्ण बंद भागने है होता है और कहीं न कहीं प्रकट करने के लिए एक पूर्ण बंद की उम्मीद होगी
  • भागने/इस तरह बनाने के लिए यह एक लाइट के रूप में राल \/
  • क्या है | के लिए विभाजक? कि दो विशेष रूप से आपसी भागों बना रहा है - या तो 'पूर्णांक' या एक एक 'dentor' ... वह हिस्सा भ्रमित लग रहा है के साथ 'numtor' ...
+0

'/' regexes में कोई विशेष अर्थ नहीं है। कुछ स्वाद इसे रेगेक्स * अक्षर * (जावास्क्रिप्ट, उदाहरण के लिए) के लिए एक डिलीमीटर के रूप में उपयोग करते हैं, लेकिन .NET में यह सिर्फ एक और चरित्र है; आपको इसे बचाना नहीं है। –

+0

उत्तर देने के लिए समय लेने के लिए धन्यवाद, लेकिन मुझे रेगेक्स विश्लेषण की आवश्यकता नहीं थी - यह प्रश्न में इस मुद्दे को दिखाने के लिए यहां है। – Dinah

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