2009-08-18 9 views
6

मैं एक regex की जरूरत है संख्यात्मक मान किRegex अंतरराष्ट्रीय फ्लोटिंग प्वाइंट संख्या पार्स करने के लिए

111.111,11 

111,111.11 

111,111 

हो और सही सिंटैक्स साथ पूर्णांक और दशमलव भागों को अलग एक DB में तो मैं स्टोर कर सकते हैं कर सकते हैं पाने के लिए

मुझे कोई सफलता के साथ ([0-9]{1,3}[,.]?)+([,.][0-9]{2})? की कोशिश की है, क्योंकि यह दूसरे भाग :(पता नहीं लगा पाया

परिणाम तरह दिखना चाहिए:

111.111,11 -> $1 = 111111; $2 = 11 
+0

जिज्ञासा से बाहर, आपके पास कभी भी पैटर्न क्यों होगा: 11.111,111, जो वास्तविक मूल्य (111,111.11) – ennuikiller

+0

के विपरीत है, यह बेवकूफ सबूत बनाने के लिए। ताकि उपयोगकर्ताओं को याद रखना पड़े कि सही पैटर्न क्या है – LuRsT

+0

यह वास्तव में काफी स्मार्ट है, क्योंकि दुनिया में कई देश अल्पविरामक के रूप में अल्पविराम का उपयोग कर रहे हैं। एक सूची के लिए, यहां जांचें: http://en.wikipedia.org/wiki/Decimal_separator#Countries_using_Arabic_numerals_with_decimal_comma –

उत्तर

9

सबसे पहले उत्तर:

यह #,###,##0.00 मेल खाता है:

^[+-]?[0-9]{1,3}(?:\,?[0-9]{3})*(?:\.[0-9]{2})?$ 

और यह #.###.##0,00 मेल खाता है:

^[+-]?[0-9]{1,3}(?:\.?[0-9]{3})*(?:\,[0-9]{2})?$ 

में शामिल होने से दो (वहाँ यह लिखने के लिए होशियार/कम तरीके हैं, लेकिन यह काम करता है):

(?:^[+-]?[0-9]{1,3}(?:\,?[0-9]{3})*(?:\.[0-9]{2})?$) 
|(?:^[+-]?[0-9]{1,3}(?:\.?[0-9]{3})*(?:\,[0-9]{2})?$) 

आप यह भी जांचने के लिए अंतिम कॉमा (या डॉट) में कैप्चरिंग समूह जोड़ सकते हैं कि किस का उपयोग किया गया था।


दूसरा उत्तर:

एलन एम द्वारा बताया के रूप में, अपने पिछले समाधान 11,111111.00 की तरह एक मूल्य के अस्वीकार करने के लिए जहां एक अल्पविराम याद आ रही है विफल हो सकता है, लेकिन अन्य नहीं है।

^[+-]?[0-9]{1,3} 
(?:(?<comma>\,?)[0-9]{3})? 
(?:\k<comma>[0-9]{3})* 
(?:\.[0-9]{2})?$ 

यह कुछ स्पष्टीकरण के हकदार: कुछ परीक्षण करने के बाद मैं निम्नलिखित regex कि इस समस्या से बचा जाता है पर पहुंच गया

  • ^[+-]?[0-9]{1,3} से मेल खाता है पहले (1 से 3) अंक;

  • (?:(?<comma>\,?)[0-9]{3})? वैकल्पिक अल्पविराम पर मिलान के बाद 3 अंकों के बाद, और 'अल्पविराम' नामक समूह में अल्पविराम (या एक की अयोग्यता) को कैप्चर करता है;

  • (?:\k<comma>[0-9]{3})* पहले से उपयोग किए गए अल्पविराम के किसी भी दोहराव से मेल खाता है (यदि कोई है) 3 अंकों के बाद;

  • (?:\.[0-9]{2})?$ स्ट्रिंग के अंत में वैकल्पिक "सेंट" से मेल खाता है।

बेशक

, कि केवल #,###,##0.00 (नहीं #.###.##0,00) को कवर किया जाएगा, लेकिन आप हमेशा regexes शामिल हो सकते हैं जैसे मैं ऊपर था।


अंतिम उत्तर:

अब, एक पूर्ण समाधान। केवल पठनीयता के लिए इंडेंटेशन और लाइन ब्रेक हैं।

^[+-]?[0-9]{1,3} 
(?: 
    (?:\,[0-9]{3})* 
    (?:.[0-9]{2})? 
| 
    (?:\.[0-9]{3})* 
    (?:\,[0-9]{2})? 
| 
    [0-9]* 
    (?:[\.\,][0-9]{2})? 
)$ 

और इस बदलाव को दर्शाता विभाजक इस्तेमाल किया:

^[+-]?[0-9]{1,3} 
(?: 
    (?:(?<thousand>\,)[0-9]{3})* 
    (?:(?<decimal>\.)[0-9]{2})? 
| 
    (?:(?<thousand>\.)[0-9]{3})* 
    (?:(?<decimal>\,)[0-9]{2})? 
| 
    [0-9]* 
    (?:(?<decimal>[\.\,])[0-9]{2})? 
)$ 

संपादित 1: "सेंट" अब वैकल्पिक हैं; संपादित 2: पाठ जोड़ा गया; संपादित करें 3: दूसरा समाधान जोड़ा गया; संपादित करें 4: पूरा समाधान जोड़ा गया; संपादित करें 5: शीर्षक जोड़ा गया; संपादित करें 6: जोड़ा कैप्चरिंग; संपादित करें 7: अंतिम उत्तर दो संस्करणों में टूट गया;

+0

+1। मैं विकल्प के बाहर एंकरों को ले जाऊंगा। आप इसके बाहर के सामान्य अग्रणी और पीछे वाले तत्वों को भी स्थानांतरित कर सकते हैं, लेकिन यह पठनीयता में व्यापार के लायक नहीं है –

+0

पठनीयता नियमित अभिव्यक्तियों का एक मजबूत बिंदु नहीं है, लेकिन मैं सहमत हूं। वोट के लिए धन्यवाद :) – jpbochi

+0

बस ध्यान दिया, हजारों विभाजक * वैकल्पिक नहीं होना चाहिए; उदाहरण के लिए, '(?: \।? [0-9] {3}) *' होना चाहिए (?: \। [0-9] {3}) * '। अन्यथा, आप '11,111111.00' या' 1111.111,00' जैसी चीज़ों से मेल खा सकते हैं। –

1

कैसे के बारे में

/(\d{1,3}(?:,\d{3})*)(\.\d{2})?/ 

अगर आप मान्य कि अल्पविराम के हर 3 अंक अलग वास्तव में के बारे में परवाह, या

/(\d[\d,]*)(\.\d{2})?/ 

यदि आप ऐसा नहीं करते।

+0

यह उसका पहला उदाहरण मान्य नहीं करेगा; 111.111,11 –

+0

सच है। मैंने उसे नहीं देखा। माफ़ कीजिये। – Avi

0

यदि मैं आपका प्रश्न सही तरीके से व्याख्या कर रहा हूं ताकि आप परिणाम कह रहे हों कि आप जो कहेंगे, वह "जैसा दिखता है" जैसा दिखता है, तो मुझे लगता है कि आपको चरित्र वर्ग से बाहर कॉमा छोड़ना होगा, क्योंकि यह एक विभाजक के रूप में प्रयोग किया जाता है और मिलान का क्या हिस्सा है इसका एक हिस्सा नहीं है।

तो "।" से छुटकारा पाएं। पहले, फिर दो भागों से मेल खाते हैं।

$value = "111,111.11"; 
$value =~ s/\.//g; 
$value =~ m/(\d+)(?:,(\d+))?/; 

$ 1 = समय के साथ अग्रणी पूर्णांकों $ 2 या तो undef अगर यह मौजूद नहीं था, या बाद अल्पविराम अंक हटाया = अगर वे मौजूद हैं।

3

मैं पहली बार उपयोग में इस regex एक अल्पविराम मौसम निर्धारित करने के लिए होगा या एक बिंदु एक अल्पविराम परिसीमक के रूप में प्रयोग किया जाता है (यह दो के अंतिम हासिल करेगा):

[0-9,\.]*([,\.])[0-9]* 

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

तब आपको एक पूर्णांक के रूप में एक संख्या के साथ छोड़ दिया जाता है जिसके बाद कॉमा या डॉट और फिर दशमलव होते हैं, जहां पूर्णांक- और दशमलव-भाग को आसानी से निम्नलिखित रेगेक्स के साथ एक दूसरे से अलग किया जा सकता है।

([0-9]+)[,\.]?([0-9]*) 

शुभकामनाएँ!

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

यहाँ एक उदाहरण अजगर में की गई है, मैं, मान लें कोड आत्म समझा जाना चाहिए अगर यह, बस नहीं पूछ रहा है।

import re 

input = str(raw_input()) 
delimiterRegex = re.compile('[0-9,\.]*([,\.])[0-9]*') 
splitRegex = re.compile('([0-9]+)[,\.]?([0-9]*)') 

delimiter = re.findall(delimiterRegex, input) 

if (delimiter[0] == ','): 
    input = re.sub('[\.]*','', input) 
elif (delimiter[0] == '.'): 
    input = re.sub('[,]*','', input) 

print input 

इस कोड के साथ, निम्नलिखित आदानों इस देता है:

  • 111।111,11

    111111,11

  • 111,111.11

    111111,11

  • 111.111

    111.111

इस चरण के बाद, अब आपकी आवश्यकताओं से मेल खाने के लिए स्ट्रिंग को आसानी से संशोधित कर सकते हैं।

+0

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

+0

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

+0

ओपी के अनुसार, '111,111' में अल्पविराम हजारों विभाजक (टीएस) है। एक दशमलव विभाजक (डीएस), यदि मौजूद है, तो उसके बाद दो अंकों का पालन किया जाना चाहिए (उन्होंने प्रश्न के तहत टिप्पणियों में इसे साफ़ कर दिया)। तो आपके पहले रेगेक्स को '([,।] [0-9] {2}) के साथ समाप्त होना होगा?' ओपी की तरह। लेकिन वह यह भी सत्यापित करने की कोशिश कर रहा है कि टीएस सही तरीके से वितरित किए गए हैं। –

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