2010-01-27 6 views
5

यहां पर कई पोस्ट हैं जो मूल्य पर कब्जा करते हैं, लेकिन मैं यह देखने के लिए देख रहा हूं कि मूल्य कुछ है या नहीं। अधिक अस्पष्ट रूप से डाल दिया; मैं मूल्य की जांच करने और मूल्य को "कैप्चरिंग" के बीच अंतर को समझना चाहता हूं। वर्तमान स्थिति में मूल्य निम्नलिखित स्वीकार्य धन प्रारूप होगा:क्या कोई पैसा रेजेक्स समझा सकता है जो सिर्फ यह जांचता है कि मूल्य कुछ पैटर्न से मेल खाता है या नहीं?

Here is a post जो कुछ पैसे के बारे में बताता है लेकिन मुझे यह समझ में नहीं आता है।

.50 
50 
50.00 
50.0 
$5000.00 
$.50 

मुझे अल्पविराम नहीं चाहिए (लोगों को यह हास्यास्पद होना चाहिए)।

बात मैं कुछ समस्या आ रही हैं:

  1. मूल्य की शुरुआत में एक $ के लिए अनुमति दे (लेकिन अभी भी वैकल्पिक)
  2. केवल 1 दशमलव बिंदु के लिए अनुमति दे (लेकिन यह पर अनुमति नहीं दे रहा अंत)
  3. यह समझना कि यह
  4. के अंदर कैसे काम कर रहा है यह समझने के लिए कि सामान्यीकृत संस्करण (केवल अंक और वैकल्पिक दशमलव बिंदु) प्राप्त करने के लिए समझें जो डॉलर के संकेत को स्ट्रिप करता है।

मेरे वर्तमान regex (जो स्पष्ट रूप से सही काम नहीं करता है) है:

# I'm checking the Boolean of the following: 
re.compile(r'^[\$][\d\.]$').search(value) 

(नोट: मैं अजगर में काम कर रहा हूँ)

+0

आपको लगता है कि मौद्रिक मूल्य में अल्पविराम हास्यास्पद कर रहे हैं? कई संस्कृतियां दशमलव के बजाए अल्पविराम का उपयोग करके अपने मौद्रिक मूल्यों को लिखती हैं; उदाहरण के लिए, € 4,99। – Rob

+0

अपने प्रश्न में आप "केवल 1 दशमलव बिंदु के लिए अनुमति दे रहे हैं (लेकिन इसे अंत में अनुमति नहीं दे रहे हैं)", लेकिन एक टिप्पणी में आप पूछते हैं कि इसे कैसे बनाया जाए ताकि यह अंत में मेल खा सके ... आप कौन चाहते हैं? दोनों? –

उत्तर

14

मान लिया जाये कि आप $5. नहीं लेकिन 5. अनुमति देना चाहते हैं, निम्नलिखित अपनी भाषा को स्वीकार करेंगे:

money = re.compile('|'.join([ 
    r'^\$?(\d*\.\d{1,2})$', # e.g., $.50, .50, $1.50, $.5, .5 
    r'^\$?(\d+)$',   # e.g., $500, $5, 500, 5 
    r'^\$(\d+\.?)$',   # e.g., $5. 
])) 

समझने के लिए महत्वपूर्ण टुकड़े:

  • ^ और $ क्रमशः इनपुट स्ट्रिंग की शुरुआत और अंत में मेल खाता है।
  • \. एक शाब्दिक डॉट
  • \$ एक शाब्दिक डॉलर साइन
    • \$? डॉलर चिन्ह या कुछ भी नहीं (यानी, एक वैकल्पिक डॉलर चिह्न)
  • \d मैचों किसी भी एकल अंक से मेल खाता है से मेल खाता है से मेल खाता है (0-9)
    • \d* matche शून्य का रों रन या अधिक अंकों
    • \d+ मैचों एक या अधिक संख्याएं
    • \d{1,2} मैचों किसी भी एकल अंक या दो अंक

parenthesized subpatterns के एक रन के रन पर कब्जा समूह हैं: सभी पाठ कैप्चर समूह में उप-संपीड़न से मेल खाने वाले इनपुट में matchobj.group(index) में उपलब्ध होगा। डॉलर का संकेत नहीं पकड़ा जाएगा क्योंकि यह कोष्ठक के बाहर है।

क्योंकि पाइथन एक ही नाम (!!!) के साथ कई कैप्चर समूहों का समर्थन नहीं करता है, इसलिए हमें से None पर खोज करना होगा। इसका मतलब यह भी है कि राशि को छोड़कर प्रत्येक समूह के लिए (?:...) का उपयोग करने के लिए पैटर्न को संशोधित करते समय आपको सावधान रहना होगा।

मार्क अच्छा परीक्षण दोहन ट्वीक पर हम पाते हैं

for test, expected in tests: 
    result = money.match(test) 
    is_match = result is not None 
    if is_match == expected: 
     status = 'OK' 
     if result: 
     amt = [x for x in result.groups() if x is not None].pop() 
     status += ' (%s)' % amt 
    else: 
     status = 'Fail' 
    print test + '\t' + status 

आउटपुट:

 
.50  OK (.50) 
50  OK (50) 
50.00 OK (50.00) 
50.0 OK (50.0) 
$5000 OK (5000) 
$.50 OK (.50) 
$5.  OK (5.) 
5.  OK 
$5.000 OK 
5000$ OK 
$5.00$ OK 
$-5.00 OK 
$5,00 OK 
     OK 
$  OK 
.  OK 
.5  OK (.5)
+2

+1। –

+0

मैं $ 5 कैसे बना सकता हूं। मैच (तकनीकी रूप से मैं इस मूल्य की अनुमति दे सकता हूं)। – orokusaki

+0

आपने अपने प्रश्न में यह बताया था कि आप अंत में एक अवधि की अनुमति नहीं देना चाहते थे। –

3

मेरा मानना ​​है कि निम्नलिखित regex अपनी आवश्यकताओं को पूरा करेगा :

/^\$?(\d*(\.\d\d?)?|\d+)$/ 

यह वैकल्पिक '$' की अनुमति देता है। यह एक वैकल्पिक दशमलव के लिए अनुमति देता है, लेकिन दशमलव मौजूद होने पर दशमलव के बाद कम से कम एक की आवश्यकता होती है लेकिन दशमलव के बाद दो अंकों से अधिक नहीं होती है।

संपादित करें: बाहरी कोष्ठक आपके लिए संपूर्ण संख्यात्मक मूल्य प्राप्त करेंगे।

+0

सभी मैचों को एक सूची में वापस कर दिया जाता है। 'समूह (1)' पूरी मिलान वाली स्ट्रिंग देता है, फिर बाद के समूह मिलान किए गए समूहों को वापस लौटाते हैं। '। समूह (3) 'दशमलव के बाद केवल दशमलव और अंकों को वापस कर देना चाहिए यदि वे मौजूद हैं। आपके उद्देश्यों के लिए, 'समूह (2)' हमेशा आपको पूरा नंबर देना चाहिए। – Aaron

+1

आपका पैटर्न खाली स्ट्रिंग और एक अकेला डॉलर चिह्न दोनों से मेल खाता है। नियमित अभिव्यक्तियों के साथ, याद रखें कि '* 'और'?' क्वांटिफायर * हमेशा * सफल होते हैं। –

+0

gbacon: +1 अतिरिक्त टेस्टकेस के लिए अच्छा सुझाव ... मैंने इन्हें अपने परीक्षणों में भी जोड़ा। –

4

डॉलर के संकेत को स्ट्रिप करने वाले सामान्यीकृत संस्करण (केवल अंक और वैकल्पिक दशमलव बिंदु) प्राप्त करने के लिए भी समझें।

यह भी रूप में "कब्जा" मूल्य में जाना जाता है;)

बंद कार्य हारून के आधार उदाहरण:

/^\$?(\d+(?:\.\d{1,2})?)$/ 

फिर राशि (डॉलर चिह्न के बिना) पर कब्जा समूह 1 में होगा ।

+0

यह ध्यान देने योग्य हो सकता है कि '(?:)' एक गैर-कैप्चरिंग समूह है। – Joel

+0

आपने मुझे पकड़ा! मैं उस अंतिम भाग में जोड़ना भूल गया। – Aaron

+0

यदि आप चाहें तो अपनी पोस्ट संपादित कर सकते हैं। बीटीडब्ल्यू, मैंने अपना प्रश्न संपादित किया क्योंकि मैं यह उल्लेख करने में असफल रहा कि मुझे $ 50 और .50 को भी स्वीकार करने में सक्षम होना चाहिए। – orokusaki

6

यहाँ एक regex है आप का उपयोग कर सकते हैं:

regex = re.compile(r'^\$?(\d*(\d\.?|\.\d{1,2}))$') 

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

tests = [ 
    ('.50', True), 
    ('50', True), 
    ('50.00', True), 
    ('50.0', True), 
    ('$5000', True), 
    ('$.50', True), 
    ('$5.', True), 
    ('$5.000', False), 
    ('5000$', False), 
    ('$5.00$', False), 
    ('$-5.00', False), 
    ('$5,00', False), 
    ('', False), 
    ('$', False), 
    ('.', False), 
] 

import re 
regex = re.compile(r'^\$?(\d*(\d\.?|\.\d{1,2}))$') 
for test, expected in tests: 
    result = regex.match(test) 
    is_match = result is not None 
    print test + '\t' + ('OK' if is_match == expected else 'Fail') 

$ के बिना मूल्य पाने के लिए आपको कब्जा समूह का उपयोग कर सकते हैं:

print result.group(1) 
+0

thx 1+ भी आपके पर। – orokusaki

+0

मैंने $ 5 की अनुमति देने के लिए मेरी टिप्पणी बदल दी। gbacon के जवाब पर आपकी टिप्पणी के आधार पर इसे अस्वीकार करने के बजाय। वास्तव में आपके समाधान का परीक्षण करने के लिए –

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

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