"अब आपको दो समस्याएँ हैं" से क्या मतलब है?


200

जेमी ज़्विन्स्की का एक लोकप्रिय उद्धरण है :

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

इस उद्धरण को कैसे समझा जाना चाहिए?


46
दूसरी समस्या यह है कि वे regex का उपयोग कर रहे हैं और अभी भी पहली समस्या का समाधान नहीं किया है, इसलिए 2 समस्याएं।
Ampt

24
@Euphoric - वास्तव में, अच्छा कोड है लेकिन रहस्यमय ढंग से संक्षिप्त किया जा रहा बिना - कम।
स्टीव

24
@IQAndreas: मुझे लगता है कि यह अर्ध-विनोदी होना है। जो टिप्पणी की जा रही है वह यह है कि यदि आप सावधान नहीं हैं, तो नियमित अभिव्यक्तियों का उपयोग करने से चीजें बेहतर होने के बजाय और भी बदतर हो सकती हैं।
FrustratedWithFormsDesigner

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

जवाबों:


220

कुछ प्रोग्रामिंग प्रौद्योगिकियों को आमतौर पर प्रोग्रामर ( नियमित अभिव्यक्ति , फ्लोटिंग पॉइंट , पर्ल , एडब्ल्यूके , आईओसी ... और अन्य ) द्वारा अच्छी तरह से नहीं समझा जाता है ।

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

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

यह कहना नहीं है कि नियमित अभिव्यक्तियों का उपयोग नहीं किया जाना चाहिए, बल्कि यह समझने के लिए काम करना चाहिए कि वे उन समस्याओं का क्या सेट कर सकते हैं जिन्हें वे हल कर सकते हैं और उन्हें विवेकपूर्ण तरीके से हल नहीं कर सकते हैं।

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

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


8
मुझे यकीन नहीं है कि perl खुद प्रौद्योगिकियों की एक सूची में शामिल हैं, जो प्रोग्रामर द्वारा अच्छी तरह से समझ में नहीं आती हैं;)
crad

21
@ इसके बारे में और अधिक यह भी कहा गया है कि यह पर्ल के बारे में भी कहा गया है ... कई लोगों ने सुना है कि यह वहां लोकप्रिय है। मुझे अब भी रैंड टॉक में फ्लोटिंग पॉइंट एक पसंद है: "अब आपको 2.00000152 समस्याएं हैं"

56
@ कुछ लोग, जब किसी समस्या का सामना करते हैं, तो सोचते हैं "मुझे पता है, मैं पर्ल का उपयोग करूंगा।" अब उनके पास $ (^ @ #% () ^%) (#) समस्याएं हैं।
माइकल हैम्पटन

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

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

95

नियमित अभिव्यक्तियाँ - विशेष रूप से गैर तुच्छ व्यक्ति - कोड को समझना, बनाए रखना और बनाना मुश्किल हैं। आपको केवल स्टैक ओवरफ्लो पर प्रश्नों की संख्या को देखना होगा [regex]जहां प्रश्नकर्ता ने यह मान लिया है कि उनकी समस्या का उत्तर एक रेगेक्स है और बाद में अटक गया है। बहुत सारे मामलों में समस्या (और शायद) को एक अलग तरीके से हल किया जा सकता है।

इसका मतलब यह है कि, यदि आप एक रेगेक्स का उपयोग करने का निर्णय लेते हैं, तो आपको दो समस्याएं हैं:

  1. मूल समस्या जिसे आप हल करना चाहते थे।
  2. रेगेक्स का समर्थन।

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


27
और इससे भी बदतर: वे बस शक्तिशाली हैं जो लोगों को उन चीजों को पार्स करने के लिए उपयोग करने की कोशिश कर रहे हैं जो वे नहीं कर सकते हैं, जैसे कि HTML। SO पर "मैं HTML को पार्स कैसे करूं?" पर कई प्रश्न देखें।
फ्रैंक शीयर

6
कुछ स्थितियों के लिए रेगेक्स कमाल है। कई अन्य मामलों में ऐसा नहीं है। दूसरे छोर पर यह निराशा का एक भयावह गड्ढा है। समस्या अक्सर तब होती है जब कोई पहली बार उनके बारे में सीखता है और हर जगह एप्लिकेशन देखना शुरू कर देता है। एक और प्रसिद्ध कहावत: "जब आपके पास एकमात्र उपकरण एक हथौड़ा है, तो सब कुछ एक नाखून की तरह दिखता है।"
टॉड विलियमसन

3
क्या इसका मतलब है कि SO [c #] टैग में प्रश्नों की संख्या से, यह समझने के लिए सबसे कठिन प्रोग्रामिंग भाषा है?

2
मैं बहुत अधिक स्ट्रिंग विधियों के लिए कॉल की एक लंबी श्रृंखला की तुलना में एक जटिल नियमित अभिव्यक्ति देखेंगे। OTOH, मैं वास्तव में जटिल भाषाओं को पार्स करने के लिए नियमित अभिव्यक्तियों का दुरुपयोग देखकर नफरत करता हूं।
केविन क्लाइन

5
"मूल रूप से, मुझे लगता है कि उनका मतलब है कि आपको केवल रेगेक्स का उपयोग करना चाहिए, अगर आपकी समस्या को हल करने का कोई अन्य तरीका नहीं है। कोई अन्य समाधान कोड, रखरखाव और समर्थन के लिए आसान होने जा रहा है।" - गंभीरता से असहमत .. Regexes उत्कृष्ट उपकरण हैं, आपको बस उनकी सीमाओं को जानना होगा। बहुत सारे कार्यों को रीगेक्स के साथ अधिक सुरुचिपूर्ण ढंग से कोडित किया जा सकता है। (लेकिन, सिर्फ एक उदाहरण बनाने के लिए, आपको उन्हें HTML को पार्स करने के लिए उपयोग नहीं करना चाहिए)
Karoly Horvath

69

यह ज्यादातर एक जीभ-इन-गाल मजाक है, भले ही सच्चाई का एक अनाज है।

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

हालांकि, अंकल बेन को खुश करने के लिए:

बड़ी स्पष्टता के साथ बड़ी जिम्मेदारी आती है।

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

कुछ चीजें शुरू में नियमित अभिव्यक्ति के लिए एक अच्छे काम की तरह दिखती हैं, लेकिन ऐसा नहीं है। उदाहरण के लिए, नेस्टेड टोकन के साथ कुछ भी, जैसे HTML। कभी-कभी लोग एक सरल अभिव्यक्ति का उपयोग करते हैं जब एक सरल विधि अधिक स्पष्ट होती है। उदाहरण के लिए, string.endsWith("ing")बराबर रेगेक्स की तुलना में समझना आसान है। कभी-कभी लोग एक बड़ी समस्या को एक एकल रेगेक्स में रटने की कोशिश करते हैं, जहां इसे टुकड़ों में तोड़ना अधिक उचित होता है। कभी-कभी लोग एक ही काम करने के लिए एक अच्छी तरह से नामित फ़ंक्शन बनाने के बजाय, एक रेगेक्स को बार-बार दोहराते हुए उचित सार बनाने में विफल होते हैं (शायद आंतरिक रूप से एक रेगेक्स के साथ लागू किया जाता है)।

किसी कारण के लिए, regexes के पास एकल जिम्मेदारी और DRY जैसे सामान्य सॉफ्टवेयर इंजीनियरिंग सिद्धांतों के लिए एक अंधे स्थान बनाने की एक अजीब प्रवृत्ति है। इसलिए कई बार प्यार करने वाले लोग भी उन्हें समस्याग्रस्त पाते हैं।


10
क्या अंकल बेन ने भी नहीं कहा "हर बार सही परिणाम"? शायद इसीलिए लोग रेगेक्स से खुश हो उठते हैं ...
डॉयल

4
HTML के बारे में regex के साथ समस्या यह है कि अनुभवहीन डेवलपर्स की यात्राएं यह है कि HTML में एक संदर्भ-मुक्त व्याकरण है, नियमित नहीं: regex का उपयोग कुछ सरल HTML (या XML) पार्सिंग के लिए किया जा सकता है (जैसे नामांकित टैग से URL हथियाना), लेकिन कुछ भी जटिल के लिए अच्छी तरह से अनुकूल नहीं है। उसके लिए, DOM पार्सिंग अधिक उपयुक्त है। संबंधित पढ़ना: चॉम्स्की पदानुक्रम

53

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

1997 के मूल में जेमी के पदों के पूर्ण पाठ का विश्लेषण करते हुए, हम निम्नलिखित पाते हैं:

पर्ल की प्रकृति लगभग सभी अन्य तकनीकों के बहिष्करण के लिए नियमित अभिव्यक्ति के उपयोग को प्रोत्साहित करती है; वे बिंदु A से बिंदु B पर जाने के लिए सबसे अधिक "स्पष्ट" (कम से कम, ऐसे लोगों को, जो किसी भी बेहतर नहीं जानते हैं) से दूर हैं।

पहली बोली को भी गंभीरता से लिया जाना चाहिए। लेकिन यह, मैं पूरी तरह से सहमत हूं। यहाँ बिंदु जेमी बनाने की कोशिश कर रहा था: ऐसा नहीं है कि नियमित अभिव्यक्तियाँ बुराई हैं, प्रति se, लेकिन नियमित अभिव्यक्ति का अति प्रयोग बुराई है।

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

एक और ब्लॉग पोस्ट है जो उद्धरण के संदर्भ में दिखता है, और एटवुड की तुलना में अधिक विवरण में है: जेफरी फ्रिडल का ब्लॉग: प्रसिद्ध "अब आपको दो समस्याएं हैं" स्रोत


3
यह मेरे दिमाग में है, सबसे अच्छा जवाब क्योंकि यह संदर्भ जोड़ता है। jwz regexes की आलोचना पर्ल के बारे में जितनी भी थी।
इविक्टोस

3
@ ईवीकाटोस 1997 के एक अन्य ब्लॉग पोस्ट में उसी शोध पर और भी अधिक शोध किया गया था: regex.info/blog/2006-09-15/247
IQAndreas

30

इस उद्धरण के साथ कुछ बातें चल रही हैं।

  1. बोली एक पहले मजाक के एक restatement है:

    जब भी किसी समस्या का सामना करना पड़ता है, तो कुछ लोग कहते हैं "आओ AWK का उपयोग करें।" अब, उन्हें दो समस्याएं हैं। - डी। तिलब्रुक

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

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

  3. यद्यपि एक मजाक के रूप में अजीब है, आपको रेगेक्स समाधान की जटिलता के साथ गैर-रेगेक्स समाधान की जटिलता की तुलना करने की आवश्यकता है + रीजेक्स सहित अतिरिक्त जटिलता। Regexes जोड़ने की अतिरिक्त लागत के बावजूद, एक रेगेक्स के साथ समस्या को हल करना सार्थक हो सकता है।


21

RegularExpressionsarenoworsetoreadormaintainthananyotherunformattedcontent; indeedaregexisprobablyeasiertoreadthanthispieceoftexthere-butunfortunatelytheyhaveabadreputationbecausesomeimplementationsdon'tallowformattingandpeopleingeneraldon'tknowthatyoucandoit।

(रेगुलर एक्सप्रेशंस पढ़ने या किसी अन्य अनफ़ॉर्मेंट कंटेंट को बनाए रखने के लिए बदतर नहीं हैं; वास्तव में एक रेगेक्स शायद यहाँ पाठ के इस टुकड़े की तुलना में पढ़ना आसान है - लेकिन दुर्भाग्य से उनकी एक खराब प्रतिष्ठा है क्योंकि कुछ कार्यान्वयन सामान्य रूप से प्रारूपण और लोगों को अनुमति नहीं देते हैं यह नहीं जानते कि आप इसे कर सकते हैं।)


यहाँ एक तुच्छ उदाहरण दिया गया है:

^(?:[^,]*+,){21}[^,]*+$


जो वास्तव में वैसे भी पढ़ना या बनाए रखना मुश्किल नहीं है, लेकिन जब यह इस तरह दिखता है तो और भी आसान है:

(?x)    # enables comments, so this whole block can be used in a regex.
^       # start of string

(?:     # start non-capturing group
  [^,]*+  # as many non-commas as possible, but none required
  ,       # a comma
)       # end non-capturing group
{21}    # 21 of previous entity (i.e. the group)

[^,]*+  # as many non-commas as possible, but none required

$       # end of string

यह एक ओवर-द-टॉप उदाहरण का एक सा है (टिप्पणी $करना टिप्पणी के समान है i++) लेकिन स्पष्ट रूप से इसे पढ़ने, समझने और बनाए रखने में कोई समस्या नहीं होनी चाहिए।


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


1
ज़रूर, लेकिन मैं regexs के गुणों की चर्चा नहीं कर रहा हूँ, और मैं इस चर्चा को इस तरह से देखना नहीं चाहूँगा। मैं बस समझने की कोशिश कर रहा हूं कि वह क्या कर रहा था।
पॉल बिगगर

1
फिर लिवीबेट्टर की टिप्पणी में लिंक आपको बताता है कि आपको क्या जानना है। यह प्रतिक्रिया केवल यह इंगित कर रही है कि रेगीक्स को अस्पष्ट होने की आवश्यकता नहीं है, और इस प्रकार उद्धरण बकवास है।
पीटर बॉटन

8
उपयोग की बात क्या है *+? कैसे है कि किसी भी अलग (कार्यात्मक) बस से *?
टिमवी

1
जबकि आप जो कहते हैं वह सच हो सकता है, यह इस विशिष्ट प्रश्न का उत्तर नहीं देता है। आपका जवाब "मेरी राय में" आमतौर पर सच नहीं है "पर उबलता है। सवाल यह नहीं है कि यह सच है या नहीं, लेकिन उद्धरण का क्या अर्थ है।
ब्रायन ओकले

2
*+इस मामले में करने का कोई मतलब नहीं है ; सब कुछ लंगर है और एक ऑटोनॉटन द्वारा एक एकल पास में मिलान किया जा सकता है जो 22 तक गिना जा सकता है। उन गैर-अल्पविराम सेटों पर सही संशोधक सिर्फ सादे पुराना है *। (क्या अधिक है, यहां लालची और गैर-लालची मिलान एल्गोरिदम के बीच कोई अंतर नहीं होना चाहिए। यह एक बहुत ही सरल मामला है।)
डोनल फैलो

14

क्रिसफ के जवाब के अलावा - वह नियमित अभिव्यक्ति "कोड को समझना, समझना और बनाए रखना मुश्किल है", इससे भी बदतर है: वे बस शक्तिशाली हैं जो लोगों को उन चीजों को पार्स करने के लिए उपयोग करने की कोशिश कर रहे हैं जो उन्हें नहीं मिल सकती हैं, जैसे कि HTML। SO पर "मैं HTML को पार्स कैसे करूं?" पर कई प्रश्न देखें। उदाहरण के लिए, SO में सभी का सबसे अधिक महाकाव्य उत्तर !


14

नियमित अभिव्यक्ति बहुत शक्तिशाली है, लेकिन उनके पास एक छोटी और एक बड़ी समस्या है; वे लिखना कठिन है, और पढ़ने के लिए असंभव है।

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

कभी-कभी नियमित अभिव्यक्तियों को केवल-लेखन कोड के रूप में संदर्भित किया जाता है। एक नियमित अभिव्यक्ति का सामना करना पड़ता है जिसे फिक्सिंग की आवश्यकता होती है, यह अभिव्यक्ति को समझने की कोशिश करने की तुलना में खरोंच से शुरू करना अक्सर तेज होता है।


1
असली समस्या यह है कि regexps उदाहरण के लिए एक पार्सर को लागू नहीं कर सकते क्योंकि वे गिन नहीं सकते कि वे वर्तमान में कितने गहरे नेस्टेड हैं।

4
@ Thorbjørn रावन एंडरसन: यह एक समस्या की तुलना में एक सीमा से अधिक है। यह केवल एक समस्या है यदि आप उसके लिए नियमित अभिव्यक्तियों का उपयोग करने का प्रयास करते हैं, और फिर यह नियमित अभिव्यक्तियों के साथ कोई समस्या नहीं है, यह आपकी विधि के चयन के साथ एक समस्या है।
गुफा

1
आप lexer (ज्यादातर भाषाओं के लिए अच्छी तरह से) के लिए REs का उपयोग ठीक कर सकते हैं, लेकिन एक तोते के पेड़ (यानी, पार्सिंग ) में टोकन स्ट्रीम को इकट्ठा करना औपचारिक रूप से उनसे परे है।
डोनल फेलो

10

समस्या यह है कि रेगेक्स एक जटिल जानवर है, और आप केवल अपनी समस्या का समाधान करते हैं यदि आप रेगेक्स का पूरी तरह से उपयोग करते हैं। यदि आप नहीं करते हैं, तो आप 2 समस्याओं को समाप्त करते हैं: आपकी मूल समस्या और regex।

आप दावा करते हैं कि यह कोड की सौ लाइनों का काम कर सकता है, लेकिन आप यह तर्क भी दे सकते हैं कि स्पष्ट, संक्षिप्त कोड की 100 लाइनें रेगेक्स की एक पंक्ति से बेहतर हैं।

यदि आपको इसके कुछ प्रमाण की आवश्यकता है: आप इस एसओ क्लासिक की जांच कर सकते हैं या एसओ रेगेक्स टैग के माध्यम से कंघी कर सकते हैं


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

1
@KonradRudolph मुझे लगता है कि इस तथ्य के कई regex पीढ़ी और सत्यापन टूल हैं कि कि regex दिखाने के लिए चला जाता है है एक जटिल तंत्र। यह मानव पठनीय (डिज़ाइन द्वारा) नहीं है और यह किसी ऐसे कोड को संशोधित करने या लिखने के लिए प्रवाह में पूर्ण परिवर्तन का कारण बन सकता है जो रेगेक्स का उपयोग करता है। दूसरे भाग के रूप में, मुझे लगता है कि यह स्पष्ट है कि P.SE पर ज्ञान के विशाल समूह से इसका मतलब है और यह कहते हुए कि "डिबगिंग कोड इसे लिखने में दोगुना कठिन है, इसलिए यदि आप सबसे चतुर कोड लिखते हैं, तो आप कर सकते हैं परिभाषा के अनुसार, यह डिबग करने के लिए पर्याप्त स्मार्ट नहीं है "
Ampt

2
यह एक उचित तर्क नहीं है। हां, यकीन है कि रेगेक्स जटिल हैं। लेकिन इतनी अन्य प्रोग्रामिंग भाषाएं हैं। Regex अधिकांश अन्य भाषाओं की तुलना में काफी कम जटिल है, और regex के लिए मौजूद उपकरण अन्य भाषाओं के लिए विकास टूल द्वारा बौने हैं (FWIW मैं बड़े पैमाने पर regex के साथ काम करता हूं और मैंने ऐसे टूल का कभी उपयोग नहीं किया है ...)। यह एक सरल सत्य है कि जटिल रीगेक्स समतुल्य गैर-रेगेक्स पार्सिंग कोड की तुलना में सरल हैं ।
कोनराड रुडोल्फ

@KonradRudolph मुझे लगता है कि हमारे पास तब सरल शब्द की परिभाषा के बारे में एक बुनियादी असहमति है। मैं आपको बताता हूं कि रेक्सक्स अधिक कुशल या और भी अधिक शक्तिशाली हो सकता है लेकिन मुझे नहीं लगता कि सरल वह शब्द है जो किसी के दिमाग में आता है जब आप रेगेक्स के बारे में सोचते हैं।
Ampt

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

7

अर्थ के दो भाग हैं:

  • सबसे पहले, आपने मूल समस्या को हल नहीं किया।
    यह संभवतः इस तथ्य को संदर्भित करता है कि नियमित अभिव्यक्ति अक्सर सामान्य समस्याओं के अधूरे समाधान पेश करती है।
  • दूसरा, आपने अब आपके द्वारा चुने गए समाधान से जुड़ी अतिरिक्त कठिनाई को जोड़ा है।
    नियमित अभिव्यक्तियों के मामले में, अतिरिक्त कठिनाई संभवतः जटिलता, रखरखाव या संदर्भित है, जो नियमित अभिव्यक्तियाँ बनाने से जुड़ी अतिरिक्त कठिनाई एक समस्या को हल करती है, जिसे हल करना नहीं चाहिए था।

7

जैसा कि आप 2014 में पूछते हैं, 1997 की संदर्भ की प्रोग्रामिंग भाषाओं पर विचार करना दिलचस्प होगा, जो आज के संदर्भ की तुलना में है। मैं यहां इस बहस में प्रवेश नहीं करूंगा लेकिन पर्ल और पर्ल के बारे में राय बहुत बदल गई है।

हालाँकि, 2013 के संदर्भ में बने रहने के लिए ( डे ल'ए ए कपे सूस लेस पॉन्स उपसर्ग), मैं एक प्रसिद्ध एक्सकेसीडी कॉमिक का उपयोग करते हुए उद्धरणों में पुनर्वित्त पर ध्यान केंद्रित करने का सुझाव दूंगा जो कि जेमी ज़ावास्की की एक सीधी बोली है :

एक्सकेसीडी से रेगेक्स, पर्ल और समस्याओं के बारे में एक कॉमिक

पहले मुझे इस कॉमिक को समझने में समस्या हुई क्योंकि यह ज़्वॉन्स्की बोली का संदर्भ था, और जे-ज़ी गीत के बोल का एक उद्धरण और जीएनयू program --help -zध्वज 2 का एक संदर्भ था, इसलिए, इसे समझना मेरे लिए बहुत अधिक संस्कृति थी।

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

तो आरंभिक उद्धरण वास्तविक जीवन की समस्याओं (दर्द?) पर आधारित एक व्यंग्यात्मक मजाक लगता है, जो चोट पहुँचाने वाले उपकरणों के साथ प्रोग्रामिंग के कारण होता है। जैसे एक हथौड़ा एक राजमिस्त्री को चोट पहुंचा सकता है, ऐसे उपकरणों के साथ प्रोग्रामिंग जो कि एक डेवलपर नहीं है यदि वह चुन सकता है कि क्या वह (मस्तिष्क, भावनाओं) को चोट पहुंचा सकता है। कभी-कभी, इस बात पर बड़ी बहस होती है कि कौन सा उपकरण सबसे अच्छा है, लेकिन यह लगभग बेकार कारण है यह आपके स्वाद या आपके प्रोग्रामिंग टीम के स्वाद , सांस्कृतिक या आर्थिक कारणों की समस्या है। इसके बारे में एक और उत्कृष्ट XKCD हास्य:

प्रोग्रामिंग टूल बहस के बारे में XKCD की एक कॉमिक

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

मैं दामियन कॉन एव्स पेरल बेस्ट प्रैक्टिसेज (2005 की एक किताब) से एक विशिष्ट उदाहरण दिखाते हुए उद्धरण के बारे में इस जवाब के साथ समाप्त करूंगा ।

वह बताते हैं कि इस तरह एक पैटर्न लिखना:

m{'[^\\']*(?:\\.[^\\']*)*'}

... इस तरह एक कार्यक्रम लिखने से ज्यादा स्वीकार्य नहीं है :

sub'x{local$_=pop;sub'_{$_>=$_[0
]?$_[1]:$"}_(1,'*')._(5,'-')._(4
,'*').$/._(6,'|').($_>9?'X':$_>8
?'/':$")._(8,'|').$/._(2,'*')._(
7,'-')._(3,'*').$/}print$/x($=).
x(10)x(++$x/10).x($x%10)while<>;

लेकिन इसे फिर से लिखा जा सकता है , यह अभी भी सुंदर नहीं है, लेकिन कम से कम अब यह जीवित है।

# Match a single-quoted string efficiently...
m{ '            # an opening single quote
    [^\\']*     # any non-special chars (i.e., not backslash or single quote)
    (?:         # then all of...`
    \\ .        # any explicitly backslashed char
    [^\\']*     #    followed by any non-special chars
    )*          # ...repeated zero or more times
    '           # a closing single quote
}x

आयताकार आकार कोड इस प्रकार का है दूसरा नहीं समस्या regexes कि एक स्पष्ट, पोषणीय और पठनीय तरीके से प्रारूपित किया जा सकता है।


2
/* Multiply the first 10 values in an array by 2. */ for (int i = 0 /* the loop counter */; i < 10 /* continue while it is less than 10 */; ++i /* and increment it by 1 in each iteration */) { array[i] *= 2; /* double the i-th element in the array */ }
5gon12eder

6

अगर कंप्यूटर विज्ञान से कोई एक चीज सीखनी चाहिए, तो वह है चोमस्की पदानुक्रम । मैं कहूंगा कि नियमित अभिव्यक्ति के साथ सभी समस्याएं संदर्भ-मुक्त व्याकरण के साथ पार्स करने के प्रयासों से आती हैं। जब आप सीएफजी में घोंसले के स्तर के लिए एक सीमा लगा सकते हैं (या सोच सकते हैं कि आप एक सीमा लगा सकते हैं), तो आप उन लंबी और जटिल नियमित अभिव्यक्तियों को प्राप्त करते हैं।


1
हाँ! सीएस पृष्ठभूमि के उस हिस्से के बिना नियमित अभिव्यक्ति सीखने वाले लोग हमेशा यह नहीं समझते हैं कि कुछ चीजें हैं जो एक गणितीय रूप से नहीं कर सकते हैं।
बेंजो

5

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

लेकिन, चीजों का आश्चर्यजनक रूप से बड़ा सेट जो प्रोग्रामर को पार्स करने की आवश्यकता है, वे एक नियमित भाषा (या इससे भी बदतर, एक नियमित भाषा द्वारा लगभग पार्स करने योग्य हैं और यदि आप केवल थोड़ा और कोड लिखते हैं ...)।

इसलिए यदि किसी को "अहा, आदत है, तो मुझे अलग से पाठ लेने की आवश्यकता है, मैं एक नियमित अभिव्यक्ति का उपयोग करूंगा", उस मार्ग से नीचे जाना आसान है, जब आपको किसी ऐसी चीज की आवश्यकता होती है जो पुश-डाउन ऑटोमेटन, सीएफजी पार्सर के करीब हो या और भी शक्तिशाली व्याकरण। वह आमतौर पर आँसू में समाप्त होता है।

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


3

jwz बस उस उद्धरण के साथ अपने घुमाव छोड़ रहा है। नियमित अभिव्यक्तियाँ किसी भी भाषा की विशेषता से अलग नहीं हैं - आसान पेंच करना, कठिनता से उपयोग करना, समय पर शक्तिशाली, कई बार अनुचित, अक्सर अच्छी तरह से प्रलेखित, अक्सर उपयोगी।

फ्लोटिंग पॉइंट अंकगणित, क्लोजर, ऑब्जेक्ट-ओरिएंटेशन, एसिंक्रोनस I / O के लिए भी यही कहा जा सकता है, या कुछ और जो आप नाम दे सकते हैं। अगर आपको नहीं पता कि आप क्या कर रहे हैं, तो प्रोग्रामिंग लैंग्वेज आपको दुखी कर सकती है।

यदि आपको लगता है कि regexes को पढ़ना मुश्किल है, तो प्रश्न में पैटर्न के उपभोग के लिए बराबर पार्सर कार्यान्वयन को पढ़ने की कोशिश करें। अक्सर रेगेक्स जीतते हैं क्योंकि वे पूर्ण पार्सर की तुलना में अधिक कॉम्पैक्ट होते हैं ... और ज्यादातर भाषाओं में, वे तेजी से भी होते हैं।

नियमित अभिव्यक्ति (या किसी अन्य भाषा सुविधा) का उपयोग करने से बचे नहीं क्योंकि एक स्व-प्रचारक ब्लॉगर अयोग्य कथन करता है। चीजों को अपने लिए आज़माएँ और देखें कि आपके लिए क्या काम करता है।


1
एफडब्ल्यूआईडब्ल्यू, फ्लोटिंग पॉइंट अंकगणित आरईएस की तुलना में अधिक मुश्किल है, लेकिन सरल प्रतीत होता है। सावधान रहें! (कम से कम मुश्किल आरईएस खतरनाक दिखने के लिए करते हैं।)
डोनल फैलो

3

मेरे पसंदीदा, इन-डेप्थ उत्तर, प्रसिद्ध रोब पाइक द्वारा एक आंतरिक Google कोड टिप्पणी से पुन: प्रस्तुत ब्लॉग पोस्ट में दिए गए हैं: http://commandcenter.blogspot.ch/2011/08/ अनियमित-expressions-in-lexing- and.html

सारांश यह है कि ऐसा नहीं है कि वे खराब हैं , लेकिन वे अक्सर उन कार्यों के लिए उपयोग किए जाते हैं जिन्हें वे आवश्यक रूप से अनुकूल नहीं हैं, खासकर जब यह कुछ इनपुट को लेक्सिंग और पार्स करने की बात आती है।

नियमित अभिव्यक्ति को लिखना मुश्किल है, अच्छी तरह से लिखना मुश्किल है, और अन्य प्रौद्योगिकियों के सापेक्ष महंगा हो सकता है ... दूसरी तरफ, लेक्सर्स, सही ढंग से लिखने के लिए काफी आसान हैं (यदि कॉम्पैक्ट रूप में नहीं), और परीक्षण करना बहुत आसान है। अल्फ़ान्यूमेरिक पहचानकर्ता खोजने पर विचार करें। रीजेक्सप ("[a-ZA-Z _] [[a-ZA-Z_0-9] *") लिखना बहुत कठिन नहीं है, लेकिन वास्तव में सरल लूप के रूप में लिखना ज्यादा कठिन नहीं है। लूप का प्रदर्शन, हालांकि, बहुत अधिक होगा और इसमें कवर के नीचे बहुत कम कोड शामिल होंगे। एक नियमित अभिव्यक्ति पुस्तकालय एक बड़ी बात है। एक पार्स आइडेंटिफ़ायर का उपयोग करना दूध की दुकान पर जाने के लिए फेरारी का उपयोग करने जैसा है।

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


0

यह एलन पर्लीस के एपिग्राम # 34 से संबंधित है:

स्ट्रिंग एक स्टार्क डेटा संरचना है और हर जगह इसे पारित किया जाता है प्रक्रिया की बहुत दोहराव है। यह जानकारी छिपाने के लिए एक आदर्श वाहन है।

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

हालांकि, अक्सर यह काम नहीं करता है: मूल समस्या हल नहीं होती है, और इसलिए उस मामले में आपको दो समस्याएं हैं।


0

त्वरित और गंदे पाठ पार्सिंग के लिए रेगेक्स का व्यापक रूप से उपयोग किया जाता है। वे पैटर्न व्यक्त करने के लिए एक महान उपकरण हैं जो केवल एक सादे स्ट्रिंग मैच की तुलना में थोड़ा अधिक जटिल हैं।

हालाँकि रेगेक्स को और अधिक जटिल सर्पिल मुद्दे मिलते हैं जो अपना सिर उठाते हैं।

  1. रीगेक्स का वाक्य विन्यास सरल मिलान के लिए अनुकूलित है, अधिकांश वर्ण स्वयं से मेल खाते हैं। यह सरल पैटर्न के लिए बहुत अच्छा है, लेकिन एक बार जब आप कुछ घोंसले के स्तर से अधिक समाप्त हो जाते हैं, तो आप अच्छी तरह से संरचित कोड की तुलना में लाइन शोर की तरह कुछ देख रहे हैं। मुझे लगता है कि आप कोड की संरचना दिखाने के लिए इंडेंटेशन और टिप्पणियों के बीच में संक्षिप्त स्ट्रिंग्स की एक श्रृंखला के रूप में एक रेगेक्स लिख सकते हैं, लेकिन वास्तव में ऐसा होना दुर्लभ प्रतीत होता है।
  2. केवल कुछ प्रकार के पाठ मिलान अच्छी तरह से रीगेक्स के अनुकूल हैं। अक्सर आप पाते हैं कि किसी तरह की मार्कअप भाषा में काम करने के लिए आप जल्दी और गंदे रेगेक्स आधारित पार्सर प्राप्त कर लेते हैं, लेकिन फिर आप अधिक कोनों को कवर करने की कोशिश करते हैं और आप पाते हैं कि रेक्सक्स अधिक से अधिक जटिल और कम और कम पठनीय हो रहा है।
  3. रेगेक्स की समय जटिलता गैर-ऑवोविअस हो सकती है। यह एक ऐसे पैटर्न के साथ समाप्त करने के लिए मुश्किल नहीं है जो मैच होने पर शानदार काम करता है लेकिन गैर-मिलान के कुछ मामलों के तहत O (2 ^ n) जटिलता है

इस प्रकार यह सब बहुत आसान है एक टेक्स्ट प्रोसेसिंग प्रॉब्लम के साथ शुरू करना, उस पर रेगुलर एक्सप्रेशन लागू करना और दो प्रॉब्लम को खत्म करना, आप जिस ऑरिजिनल प्रॉब्लम को सॉल्व करने की कोशिश कर रहे हैं और जो रेग्युलर एक्सप्रेशंस सॉल्व करने की कोशिश कर रहे हैं (सही तरीके से सॉल्व नहीं कर रहे हैं)। मूल समस्या।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.