2012-11-12 12 views
19

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

उदाहरण के लिए

, निम्नलिखित नियमित अभिव्यक्ति

/^([0-9]+|\.[0-9]+)$/ 

234 

और

से मेल खाएगी
.56 

नहीं बल्कि

234.56 

निम्नलिखित नियमित अभिव्यक्ति

/^([0-9]+)?(\.[0-9]+)?$/ 

ऊपर तार के सभी तीन से मेल करते हैं, लेकिन यह भी रिक्त स्ट्रिंग, करते हैं जो हम नहीं चाहते से मेल खाएगी।

मुझे कुछ ऐसी चीज चाहिए जो उपरोक्त सभी तीन तारों से मेल खाती है, लेकिन खाली स्ट्रिंग नहीं। क्या ऐसा करने का कोई आसान तरीका है?

अद्यतन:

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

/^\s*-?0*(?:[0-9]+|[0-9]{1,3}(?:,[0-9]{3})+)(?:\.[0-9]*)?(\s*|[A-Za-z_]*)*$/ 

यह

45 
45.988 
45,689 
34,569,098,233 
567,900.90 
-9 
-34 banana fries 
0.56 points 

से मेल खाते हैं, लेकिन यह

.56 

से मेल नहीं खाएगी और मैं इसे ऐसा करने की जरूरत: यहाँ वास्तविक regexp मैं उपयोग कर रहा हूँ है।

+0

कौन सी भाषा/रेगेक्स स्वाद? –

+0

मैं जावास्क्रिप्ट का उपयोग कर रहा हूँ। – rharrington

+0

आपका संपादन चीजों को जटिल बनाता है, लेकिन आप अभी भी इसे काफी सरल बना सकते हैं, खासकर यदि आप पहले व्हाइटस्पेस पर विभाजित होते हैं। मेरा संपादन देखें। –

उत्तर

17

पूरी तरह से सामान्य विधि, यह देखते हुए regexes /^A$/ और /^B$/ है:

/^(A|B|AB)$/ 

अर्थात

/^([0-9]+|\.[0-9]+|[0-9]+\.[0-9]+)$/ 

नोट दूसरों को अपने उदाहरण की संरचना का इस्तेमाल किया है एक सरलीकरण बनाने के लिए। विशेष रूप से, वे (अंतर्निहित) कारक को बाएं और दाएं आम [0-9]* और [0-9]+ कारकों को खींचने के लिए कारक बनाते हैं।

इस के लिए काम कर रहे है:

  • सभी [0-9]+ में प्रत्यावर्तन अंत के तत्वों, इसलिए खींच कि बाहर: /^(|\.|[0-9]+\.)[0-9]+$/
  • अब हम, प्रत्यावर्तन में रिक्त स्ट्रिंग की संभावना है तो फिर से लिखने यह ? (यानी/^(\.|[0-9]+\.)?[0-9]+$/
  • फिर, एक आम प्रत्यय के साथ एक प्रत्यावर्तन (\. इस समय): /^((|[0-9]+)\.)?[0-9]+$/
  • पैटर्न (|a+), a* रूप में एक ही है, इसलिए अंत में: /^([0-9]*\.)?[0-9]+$/
+0

धन्यवाद। मैंने उस क्रूर बल के सामान्य समाधान के बारे में भी सोचा नहीं था। – rharrington

4

हाँ, आप इस तरह के एक अभिव्यक्ति के साथ इन सभी का मिलान कर सकते हैं:

/^[0-9]*\.?[0-9]+$/ 

ध्यान दें, यह भी रिक्त स्ट्रिंग (अपने पिछले हालत) से मेल नहीं खाता।

4

निश्चित रूप से। आप वैकल्पिक क्वांटिफायर, ? चाहते हैं।

/^(?=.)([0-9]+)?(\.[0-9]+)?$/ 

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

/^\d*\.?\d+$/ 

यह खाली स्ट्रिंग को रोकने सहित आपकी आवश्यकताओं को पूरा करता है।

ध्यान दें कि इसे व्यक्त करने के कई तरीके हैं। कुछ लंबे हैं और कुछ बहुत कम हैं, लेकिन they become more complex depending on what you're trying to allow/disallow

संपादित करें:

आप एक बड़ा स्ट्रिंग के अंदर इस मैच के लिए चाहते हैं, तो मैं पर बंटवारे और /^\d*\.?\d+$/ के साथ परिणाम परीक्षण सलाह देते हैं। अन्यथा, आप aaa.123.456.bbb या लापता मैचों जैसे मिलान करने वाली चीजों को जोखिम देंगे (मेरा विश्वास करो, आप करेंगे। जावास्क्रिप्ट की तरफ से समर्थन की कमी यह सुनिश्चित करती है कि किसी भी पैटर्न को तोड़ना संभव होगा)।

आप एक तथ्य यह है कि आप ऊपर की तरह तार नहीं मिलेगा, तो आप ^$ एंकर के बजाय शब्द टूट जाता है का उपयोग कर सकते हैं, लेकिन यह . और (एक अंतरिक्ष) के बीच कोई शब्द को तोड़ने क्योंकि जटिल हो जाएगा के लिए पता है।

/(\b\d+|\B\.)?\d*\b/g 

ऐसा करना चाहिए। यह aaa123.456bbb जैसी सामग्री को अवरुद्ध कर देगा, लेकिन यह 123, 456, या 123.456 की अनुमति देगा। यह aaa.123.456.bbb की अनुमति देगा, लेकिन जैसा कि मैंने कहा है, यदि आप इसे व्यापक रूप से संभालना चाहते हैं तो आपको दो चरणों की आवश्यकता होगी।

संपादित करें 2: आपके उपयोग के मामले

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

/^\s*[-+]?\d*\.?\d+[a-z_\s]*$/i 

हजारों समूहों की अनुमति दे बहुत बातें पेचीदा हो, और मैं तुम्हें जवाब मैं से जुड़ा हुआ पर एक नज़र डालें सुझाव देते हैं।

/^\s*[-+]?(\d+|\d{1,3}(,\d{3})*)?(\.\d+)?\b(\s[a-z_\s]*)?$/i 

\b सुनिश्चित करता है कि संख्यात्मक हिस्सा अंक के साथ समाप्त होता है, और कम से कम एक खाली स्थान के द्वारा पीछा किया जाता: यहाँ जिसके परिणामस्वरूप पैटर्न है।

+0

धन्यवाद! हाँ, हमें हजारों का उपयोग करने की आवश्यकता है क्योंकि यह उपयोगकर्ता और ऐप के बीच एक पिछली चीज है, दोनों संभावित रूप से इनपुट फ़ील्ड में मान सेट कर रहे हैं। ऐप हमेशा हजारों विभाजक के साथ इनपुट बॉक्स में संख्या प्रदर्शित करेगा, इसलिए यदि उपयोगकर्ता इसे फिर से सबमिट करता है, तो हम इसे सत्यापित करना चाहते हैं। – rharrington

0

हो सकता है कि इस तुल्यता (|a|b) = (a|b)?) का उपयोग मदद करता है (आपको सामान्य विचार देने के लिए):

(?:((?(digits).^|[A-Za-z]+)|(?<digits>\d+))){1,2} 

यह पैटर्न चार के बाद वर्ण, अंक या अंक से मेल खाता है कलाकार, लेकिन अंक के बाद वर्ण नहीं। पैटर्न मिलान aa, aa11, और 11, लेकिन 11aa, aa11aa, या खाली स्ट्रिंग नहीं है। "। ^" द्वारा परेशान न हों, जिसका अर्थ है "लाइन प्रारंभ से एक वर्ण अनुवर्ती", इसका उद्देश्य किसी भी मैच को रोकने के लिए है।

चेतावनी दीजिये कि यह रेगेक्स के सभी स्वादों के साथ काम नहीं करता है, रेगेक्स के आपके संस्करण को (?(named group)true|false) का समर्थन करना चाहिए।

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

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