2008-12-10 6 views
14

ऐसा लगता है कि विकल्प बनाम नियमित अभिव्यक्ति को पार्स स्ट्रिंग का उपयोग करना किसी भी समय एक स्थिति पैदा होती है कि मैं एक स्ट्रिंग के भाग की जरूरत है, जानकारी कहा स्ट्रिंग के बारे में, आदिबुनियादी स्ट्रिंग स्प्लिटिंग/substring'ing पर नियमित अभिव्यक्तियों का उपयोग करना सबसे अच्छा कब है?

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

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

यदि आप संक्षेप में मेरी पसंद से नहीं बता सकते हैं, तो यह .NET भूमि (सी #) में है, लेकिन मेरा मानना ​​है कि इस सवाल पर ज्यादा असर नहीं पड़ता है।


संपादित: यह मेरी ठेठ Raybell आकर्षण के अनुसार लगता है, मैं भी अधिक शब्दों या मेरे सवाल में भ्रामक गया है। मैं माफी मांगना चाहता हूँ। मैं कुछ पृष्ठभूमि दे रहा था ताकि मैं जो कुछ कर रहा था, उसके बारे में सुराग देने में मदद करता हूं, लोगों को गुमराह नहीं करता।

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

मुझे आशा है कि इससे कुछ मदद मिलेगी।

+0

जब तक आप अन्यथा नहीं कहते, मुझे लगता है कि यह प्रश्न उसी प्रश्न का उत्तर देता है जो आप पूछ रहे हैं: http://stackoverflow.com/questions/56342/whats-the-best-way-of-parsing-strings – EBGreen

+0

यह करीब है मैं क्या देख रहा था। मैंने खोज की, लेकिन कुछ भी नहीं मिला जो मैंने सोचा था कि उपयुक्त था, हालांकि यह कुछ भी करीब के जैसा लगता है। –

+0

मुझे लगता है कि मैं जो पूछ रहा हूं वह यह है कि क्या वह प्रश्न आपको वह जानकारी देता है जिसे आप ढूंढ रहे थे? – EBGreen

उत्तर

21

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

एक महत्वपूर्ण दिशानिर्देश (जो कि लोगों को हर समय कोशिश करने के लिए वास्तव में मुश्किल है), हमेशा उन मामलों में एक पार्सर का उपयोग करना है जहां लक्षित भाषा का व्याकरण रिकर्सिव है।

उदाहरण के लिए, parenthetized गणित भाव के मूल्यांकन के लिए एक छोटे से "अभिव्यक्ति भाषा" पर विचार करें। इस भाषा में "कार्यक्रमों" के उदाहरण इस प्रकार दिखाई देगा:

1 + 2 
5 * (10 - 6) 
((1 + 1)/(2 + 2))/3 

एक व्याकरण लिखने के लिए आसान है, और इस तरह दिखता है:

DIGIT := ["0"-"9"] 
NUMBER := (DIGIT)+ 
OPERATOR := ("+" | "-" | "*" | "/") 
EXPRESSION := (NUMBER | GROUP) (OPERATOR EXPRESSION)? 
GROUP := "(" EXPRESSION ")" 

कि व्याकरण के साथ, आप एक पुनरावर्ती वंश का निर्माण कर सकते एक jiffy में पार्सर।

एक समान नियमित अभिव्यक्ति वास्तव में लिखना मुश्किल है, क्योंकि नियमित अभिव्यक्तियों का आमतौर पर रिकर्सन के लिए बहुत अच्छा समर्थन नहीं होता है।

एक और अच्छा उदाहरण JSON इंजेक्शन है। मैंने लोगों को नियमित अभिव्यक्तियों के साथ जेएसओएन का उपभोग करने की कोशिश की है, और यह इंसान है।जेएसओएन ऑब्जेक्ट्स रिकर्सिव हैं, इसलिए वे नियमित व्याकरण और रिकर्सिव वंश पार्सर्स के लिए भीख मांग रहे हैं।


हम्मम्मम्म ... अन्य लोगों के जवाबों को देखते हुए, मुझे लगता है कि मैंने गलत सवाल का जवाब दिया होगा।

मैं के रूप में यह व्याख्या की "जब बल्कि एक पूर्ण विकसित पार्सर से एक सरल regex का उपयोग, उपयोग करना चाहिए?" जबकि ज्यादातर लोगों के रूप में सवाल व्याख्या की है करने लगते हैं "जब आप अपने खुद के अनाड़ी तदर्थ चरित्र-दर-चरित्र सत्यापन योजना, बल्कि एक नियमित अभिव्यक्ति का उपयोग करने से रोल करना चाहिए?"

यह देखते हुए कि व्याख्या, मेरे जवाब है: कभी नहीं।


ठीक है .... एक और संपादन।

मैं रोल अपने-खुद इस योजना का थोड़ा और क्षमाशील हो जाएगा। बस ... इसे "पार्सिंग" न कहें: ओ)

मुझे लगता है कि अंगूठे का एक अच्छा नियम यह है कि आपको स्ट्रिंग-मिलान प्राइमेटिव का उपयोग करना चाहिए यदि आप एक ही भविष्यवाणी का उपयोग करके अपने सभी तर्कों को लागू कर सकते हैं। इस तरह:

if (str.equals("DooWahDiddy")) // No problemo. 

if (str.contains("destroy the earth")) // Okay. 

if (str.indexOf(";") < str.length/2) // Not bad. 

एक बार अपनी शर्तों कई विधेय होते हैं, तो आप अपने खुद तदर्थ स्ट्रिंग सत्यापन भाषा की खोज करने शुरू कर दिया है, और आप शायद अभी मनुष्य और कुछ नियमित अभिव्यक्ति का अध्ययन करना चाहिए।

if (str.startsWith("I") && str.endsWith("Widget") && 
    (!str.contains("Monkey") || !str.contains("Pox"))) // Madness. 

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

http://www.regular-expressions.info/

पुनश्च::

यहाँ एक महान संदर्भ है क्या तुमने कभी करते अपनी खुद की पारसर्स (लेक्स/याक, ANTLR, JavaCC, या अन्य के साथ लिखने के बारे में सीखना चाहते हैं एक बोनस के रूप में, यदि समान उपकरण), नियमित अभिव्यक्ति सीखना एक महान तैयारी है, क्योंकि पार्सर जनरेटर उपकरण कई सिद्धांतों का उपयोग करते हैं।

+0

मैं इस धारणा के तहत था कि "मूल स्ट्रिंग पार्सिंग" 1 .indexOf() और 2 .subString() कॉल या कुछ समान जैसी चीजों को इंगित करता है। इस तरह के जटिल चीजों के लिए, मैं निश्चित रूप से पार्सर मार्ग के साथ भी जाऊंगा। –

+0

मैं जरूरी नहीं कि चरित्र-दर-चरित्र सत्यापन कर रहा हूं। मैं बस एक सबस्ट्रिंग को पकड़ना चाहता हूं, और फिर उस पर कार्य करता हूं। आम तौर पर, मैं रेगेक्स पर substring'ing चुनने के लिए सामान्य दिशानिर्देश क्या देख रहा हूँ के लिए देख रहा हूँ। मेरा मानना ​​है कि मैं अपने प्रश्न में बहुत स्पष्ट नहीं हो सकता ... –

+0

तो, उन सभी में से, आपके हालिया संपादन के साथ पीछा किया, यह मूल रूप से मैं जो खोज रहा था। धन्यवाद! –

6

regex

  • समझने में अधिक आसान
  • अधिक स्पष्ट रूप से व्यक्त इरादे
  • बहुत कम
  • आसान बदलने के लिए/अनुकूलन

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

रेगेक्स से मुझे प्राप्त होने वाले अधिक (और संभवतः अन्य) फायदे, जितना अधिक मैं उनका उपयोग करना चाहता हूं।

अंगूठे के संभावित नियम: अगर regex समझने कोई है जो नियमित अभिव्यक्ति के साथ कुछ हद तक परिचित है के लिए मिनट ले जाएगा, तो आप नहीं है जब तक कि "सामान्य" कोड और भी अधिक जटिल है ;-) इसका इस्तेमाल करने (चाहते हैं।

एचएम ... अभी भी कोई साधारण नियम-थंब नहीं, क्षमा करें।

1

जब आपका आवश्यक परिवर्तन बुनियादी नहीं है - लेकिन अभी भी अवधारणात्मक सरल है।

Regex बाहर निकलने के लिए यदि आप एक सीधे स्ट्रिंग प्रतिस्थापन कर रहे हैं उदाहरण के लिए, ... इसकी आसान सिर्फ string.Replace

दूसरी ओर

, एक जटिल नियम कई सशर्त, साथ उपयोग करने के लिए या बिना किसी कारण विशेष मामले हैं, regex 50 से अधिक पात्रों ले जाएगा जब तक कि यह कुछ इस तरह के एक अल्पविराम बंटवारे के रूप में बहुत आसान है यदि आप स्पष्ट रूप से यह पता नहीं लिखते

0

बाद में बनाए रखने के लिए एक बुरा सपना हो सकता है मैं हमेशा एक regex का प्रयोग करेंगे अलग-अलग स्ट्रिंग। अगर मुझे लगता है कि तारों का एक मौका अधिक जटिल हो सकता है, तो शायद मैं एक रेगेक्स से शुरू करूंगा।

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

रेगेक्स शायद ही कभी अधिक है - यदि मैच सरल है, तो रेगेक्स भी है।

+0

यहां तक ​​कि कुछ सीएसवी पार्सर भी उद्धरण नियमों को लिखने के लिए भ्रामक रूप से जटिल है। (न्यूलाइन वर्ण और अल्पविराम दोनों एक ही क्षेत्र में हो सकते हैं, जब तक कि क्षेत्र उद्धरणों में संलग्न हो।) विनम्र सीएसवी को कम मत समझें !!! एक रेगेक्स के साथ भी, सही ढंग से पार्स करना वाकई मुश्किल है: ओ) – benjismith

+0

मैंने एक अल्पविराम से अलग स्ट्रिंग कहा, सीएसवी फ़ाइल नहीं। मैं CSV फ़ाइल के लिए समर्पित लाइब्रेरी या पार्सर के अलावा कुछ भी नहीं सुझाऊंगा। मैंने वास्तव में एक सी ++ सीएसवी पार्सर लिखा है जो उपर्युक्त सभी के साथ मुकाबला करता है, लेकिन मेरे पिता एक डीएफए – Draemon

2

[W] e're एक साबुन शीर्षक की कार्रवाई का मूल्यांकन करने और है कि

पर निर्णय लेने कभी नियमित अभिव्यक्ति या बुनियादी स्ट्रिंग एक्सएमएल कार्रवाई करने के लिए पार्स करने का उपयोग करें। आम उपयोग में हर भाषा में अभी पूरी तरह से अच्छा एक्सएमएल समर्थन है। एक्सएमएल एक भ्रामक जटिल मानक है और यह संभावना नहीं है कि आपका कोड इस अर्थ में सही होगा कि यह सभी अच्छी तरह से गठित XML इनपुट को सही ढंग से पार्स करेगा, और यदि ऐसा होता है, तो भी आप अपना समय बर्बाद कर रहे हैं क्योंकि (जैसा कि अभी उल्लेख किया गया है) हर भाषा में सामान्य उपयोग में एक्सएमएल समर्थन है। XML को पार्स करने के लिए नियमित अभिव्यक्तियों का उपयोग करना गैर-व्यावसायिक है।

अपने प्रश्न का उत्तर देने के लिए, आम तौर पर नियमित अभिव्यक्तियों के उपयोग को कम किया जाना चाहिए क्योंकि वे बहुत पठनीय नहीं हैं। अक्सर आप नियमित अभिव्यक्तियों की तुलना में एक बहुत ही सरल समाधान बनाने के लिए स्ट्रिंग पार्सिंग और नियमित अभिव्यक्ति (शायद एक लूप में) को जोड़ सकते हैं।

+0

थे, मैं यहां भ्रामक था, और मैं क्षमा चाहता हूं। वास्तविकता यह है कि जब तक हम इसके साथ मिल रहे हैं, तो इसे ऑपरेशन कॉन्टेक्स्ट के माध्यम से हमारे लिए पार्स किया गया है। हालांकि, इसे इंगित करने के लिए मैं आपको धन्यवाद देता हूं! –

+0

मैंने स्पष्टता को सुधारने के लिए प्रश्न को थोड़ा सा अद्यतन किया है, लेकिन ऐसा लगता है कि यह अभी भी भ्रमित है। जब मेरे पास अधिक समय लगेगा तो मैं इसे और अधिक पढ़ूंगा। मैं क्षमाप्रार्थी हूं। –

+0

क्षमा करें। मैं शायद अधिक विनम्र हो सकता था, लेकिन यह ऐसा कुछ है जो मुझे हर बार देखता है जब मैं इसे देखता हूं। – Tmdean

1

मैं क्या benjismith कहा के साथ सहमत हैं, लेकिन सिर्फ एक सा विस्तृत करना चाहते हैं। बहुत सरल वाक्यविन्यासों के लिए, मूल स्ट्रिंग पार्सिंग अच्छी तरह से काम कर सकती है, लेकिन फिर regexes कर सकते हैं। मैं उन्हें ज्यादा नहीं कहूंगा। यदि यह काम करता है, तो यह काम करता है - जो आपको सबसे सरल लगता है उसके साथ जाएं। और मध्यम से मध्यवर्ती स्ट्रिंग पार्सिंग के लिए, आमतौर पर एक रेगेक्स जाने का तरीका होता है।

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

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

+0

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

0

मुझे लगता है कि नियमित अभिव्यक्तियों का उपयोग कब और कब नहीं करना है, यह जानने का सबसे आसान तरीका है, जब आपकी स्ट्रिंग खोज को IF/THEN कथन या इस तर्क के समान कुछ भी चाहिए, तो आपको एक साधारण स्ट्रिंग से बेहतर कुछ चाहिए तुलना जहां रेगेक्स चमकता है।

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

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