2009-12-15 8 views
6

के बीच होना चाहिए, मुझे सीरियल नंबरों को सत्यापित करने की आवश्यकता है। इसके लिए हम सी # में नियमित अभिव्यक्तियों का उपयोग करते हैं, और एक निश्चित उत्पाद, धारावाहिक संख्या का हिस्सा "आधी रात से सेकंड" होता है। एक दिन में 86400 सेकंड होते हैं, लेकिन मैं कैसे इस स्ट्रिंग ?: में 5 अंकों की संख्या के रूप में यह मान्य कर सकते हैंनियमित अभिव्यक्ति जहां स्ट्रिंग का हिस्सा 0-100

654984051-86400-231324 

मैं इस अवधारणा का उपयोग नहीं कर सकते हैं:

[0-8][0-6][0-4][0-0][0-0] 

तो 86399 क्योंकि मान्य नहीं होगा। मैं इससे कैसे उबरूं? मैं कुछ की तरह हैं: - और साथ सहमत हूँ - यह स्पष्ट है कि मैं के बारे में पता कर रहा हूँ बनाने के लिए

[00000-86400] 

अद्यतन
मैं चाहता हूँ "जब वहाँ एक सरल तरीका नियमित अभिव्यक्ति का उपयोग नहीं करते" विचारधारा। Jason's answer बिल्कुल ठीक है कि मैं इसे कैसे करना चाहता हूं, हालांकि यह धारावाहिक संख्या सत्यापन हमारे सिस्टम के माध्यम से गुजरने वाले सभी धारावाहिक संख्याओं के लिए है - वर्तमान में इन विशिष्ट लोगों के लिए कोई कस्टम सत्यापन कोड नहीं है। इस मामले में मेरे पास रेगेक्स समाधान की तलाश करने का एक अच्छा कारण है।

बेशक, यदि कोई नहीं है, तो यह इन विशेष उत्पादों के लिए कस्टम सत्यापन के मामले को निर्विवाद बनाता है, लेकिन मैं समाधान के साथ जाने से पहले इस एवेन्यू को पूरी तरह से खोजना चाहता था जिसके लिए कोड परिवर्तन की आवश्यकता होती है।

+3

कुछ लोग, जब किसी समस्या का सामना करते हैं, तो सोचें "मुझे पता है, मैं नियमित अभिव्यक्तियों का उपयोग करूंगा।" अब उन्हें दो समस्याएं हैं। - जेमी ज़विंस्की –

+0

वास्तव में सच नहीं है, लेकिन मुझे इसके बारे में पढ़ने वाले ब्लॉग पोस्ट को याद नहीं किया जा सकता है। अभी भी एक अच्छा उद्धरण ... – RCIX

+0

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

उत्तर

6

एक मनमाना सांख्यिक श्रेणी http://utilitymill.com/utility/Regex_For_Range

मैच के लिए एक नियमित अभिव्यक्ति उत्पन्न

निम्नलिखित रेगेक्स अभिव्यक्ति उत्पन्न करता है:

\b0*([0-9]{1,4}|[1-7][0-9]{4}|8[0-5][0-9]{3}|86[0-3][0-9]{2}|86400)\b 

उत्पादन का विवरण:

First, break into equal length ranges: 
    0 - 9 
    10 - 99 
    100 - 999 
    1000 - 9999 
    10000 - 86400 

Second, break into ranges that yield simple regexes: 
    0 - 9 
    10 - 99 
    100 - 999 
    1000 - 9999 
    10000 - 79999 
    80000 - 85999 
    86000 - 86399 
    86400 - 86400 

Turn each range into a regex: 
    [0-9] 
    [1-9][0-9] 
    [1-9][0-9]{2} 
    [1-9][0-9]{3} 
    [1-7][0-9]{4} 
    8[0-5][0-9]{3} 
    86[0-3][0-9]{2} 
    86400 

Collapse adjacent powers of 10: 
    [0-9]{1,4} 
    [1-7][0-9]{4} 
    8[0-5][0-9]{3} 
    86[0-3][0-9]{2} 
    86400 

Combining the regexes above yields: 
    0*([0-9]{1,4}|[1-7][0-9]{4}|8[0-5][0-9]{3}|86[0-3][0-9]{2}|86400) 

यहाँ परीक्षण किया गया: http://osteele.com/tools/rework/

10

रेगेक्स का उपयोग न करें? यदि आप रेगेक्स के साथ आने के लिए संघर्ष कर रहे हैं तो यह कहने के लिए कि शायद यह बहुत जटिल है और आपको कुछ आसान मिलना चाहिए। मुझे रेगेक्स का उपयोग करने के लिए बिल्कुल कोई फायदा नहीं होता है जब एक सरल

int value; 
if(!Int32.TryParse(s, out value)) { 
    throw new ArgumentException(); 
} 
if(value < 0 || value > 86400) { 
    throw new ArgumentOutOfRangeException(); 
} 

ठीक काम करेगा। यह सिर्फ इतना स्पष्ट और आसानी से रखरखाव योग्य है।

+6

रेगेक्स एक महान, शक्तिशाली उपकरण है, लेकिन मुझे लगता है कि लोग किसी भी समय एक पार्सिंग/सत्यापन समस्या उठने पर अक्सर इसके लिए बहुत जल्दी और बहुत जल्दी पहुंचते हैं। – jason

+0

वाह, अपने घोड़ों को पकड़ें - यह धारावाहिक संख्या सत्यापन हमारे सिस्टम के माध्यम से गुजरने वाले सभी धारावाहिक संख्याओं के लिए है - इन विशिष्ट लोगों के लिए कोई कस्टम सत्यापन कोड नहीं है। यदि संभव हो तो मुझे रेगेक्स से बचने के लिए पता है, लेकिन इस मामले में * इसके लिए अच्छे कारण हैं। –

+2

यह आपके सिस्टम में हुक जोड़ने के लिए एक शानदार कारण की तरह लगता है। – Ken

7

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

match regex /(\d+)-(\d+)-(\d+)/ 
serial = capture group 2 
if serial >= 0 and serial <= 86400 then 
    // serial is valid 
end if 
-1

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

संपादित करें: यह एक regex से पहचाना जा सकता है, लेकिन एक सुरुचिपूर्ण तरीके से नहीं। इसके लिए एक राक्षस या श्रृंखला (उदा .: 00000|00001|00002 या 0{1,5}|0{1,4}1|0{1,4}2) की आवश्यकता होगी। मेरे लिए, संभावनाओं के इतने बड़े सेट को गिनने के लिए यह स्पष्ट करता है कि यह तकनीकी रूप से संभव है, लेकिन यह व्यवहार्य या प्रबंधनीय नहीं है।

+1

यह सच है? मुझे वास्तव में एफएसए के बारे में बहुत कुछ पता नहीं है, लेकिन hypothetical counterexample "00000 | 00001 | ... .... | 86400" – Jimmy

+5

यह निश्चित रूप से कर सकता है, क्योंकि 0 और 86400 के बीच प्रत्येक पूर्ण संख्या का स्ट्रिंग प्रस्तुति एक परिमित है सेट। सभी परिमित सेट एक सीमित राज्य automaton द्वारा स्वीकार किया जा सकता है। – Welbog

+0

आप दोनों मेरे चूक के बारे में निश्चित रूप से सही हैं। मैंने अपना जवाब –

0

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

([0-7][0-9]{4}) | (8[0-5][0-9]{3}) | (86[0-3][0-9]{2}) | (86400) 
+0

काम नहीं करेगा क्योंकि यह 79800 को सत्यापित करने में विफल रहता है। – Broam

+0

आप सही हैं। मैंने ठीक कर दिया। –

+0

83400 के बारे में क्या? – GalacticCowboy

6
मानक 'इस-है-नहीं-ए-विशेष रूप से-regexy-प्रोब्लम' चेतावनी के साथ

,

[0-7]\d{4}|8[0-5]\d{3}|86[0-3]\d{2}|86400 
+0

रॉबर्ट हार्वे का संस्करण 10000 से कम संख्याओं को भी संभालता है जो 0-पैड नहीं हैं। – Jimmy

0

मैं कुछ नेट कोड के साथ संयुक्त regex का उपयोग यह पूरा करने के हैं। एक बड़ी रेगेक्स समाधान बड़ी संख्या में श्रेणियों को संभालने के लिए आसान या कुशल नहीं होने वाला है।

लेकिन इस इच्छा:

Regex myRegex = new Regex(@"\d{9}-(\d{5})-\d{6}"); 
String value = myRegex.Replace(@"654984051-86400-231324", "$1"); 

यह इस मामले में मूल्य 86400 हड़पने होगा। और फिर आप जांच लेंगे कि जेसन के जवाब के अनुसार कैप्चर नंबर 0 और 86400 के बीच है या नहीं।

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