2010-01-26 18 views
9

मैं इस उदाहरण की स्थापना कर रहा हूँ पर्ल टुकड़ा एक तारीख में महीने के लिए मान्य करने के लिए:महीने इनपुट को सत्यापित करने के लिए मैं नियमित अभिव्यक्ति का उपयोग कैसे कर सकता हूं?

कुछ परिदृश्य मैं स्वीकार करना चाहते हैं:

एम.एम. एम

#!/usr/bin/perl 
use strict; 
use warnings; 

my $pattern; 
my $month = "(0[1-9]|1[012])"; 
my $day = "(0[1-9]|[12]\d|3[01])"; 

system("cls"); 

do { 

    print "Enter in a month: "; 
    chomp($pattern = <STDIN>); 

    # We only want to print if the pattern matches 
    print "Pattern matches\n" if ($pattern =~ /$month/); 


} while ($pattern ne "Q"); 

जब मैं इस चलाने के लिए, यह सही ढंग से 01-12 से फिल्टर लेकिन जब मैं करने के लिए regex बदलने के लिए:

$month = "(0?[1-9]|1[012])"; 

तो regex की अनुमति देता है 13, 14, आदि ... क्या giv es?

+0

(0 [1-0] | 1 [012]?), अमान्य [] रेंज "1-0" regex में। लेखन त्रुटि है? –

+0

मैं ग्रेग हेगिल के उत्तर से सहमत हूं लेकिन जो कारण आप प्राप्त नहीं कर रहे हैं वह कारण है क्योंकि आपकी रेगेक्स मेटाएक्टैक्टर्स को गायब कर रही है ताकि आपकी स्ट्रिंग (यानी^और $) की शुरुआत और अंत से मेल खाने के लिए रेगेक्स को बताने के लिए कहा जा सके। जैसा कि यह खड़ा है कि यह आपकी स्ट्रिंग के किसी भी भाग से मेल खाता है। – seth

उत्तर

22

तुम सच में regex का उपयोग करना चाहते हैं, तो आप डाल करने के लिए^और $, जैसे

"^(0?[1-9]|1[012])$"

यह 13, 14 से मेल नहीं खाएगी जरूरत है ....

+2

पैटर्न मिलान या खोज समस्या। –

+1

यह जावास्क्रिप्ट में भी मेरे लिए भी काम करता है। –

+0

ध्यान दें कि यह '01' और' 1' दोनों से मेल खाता है। हम में से कुछ के लिए स्पष्ट नहीं हो सकता है जो सिर्फ एसओ से कॉपी और पेस्ट करें ... – DanGordon

17

आपको संख्यात्मक सीमा सत्यापन करने के लिए नियमित अभिव्यक्ति का उपयोग नहीं करना चाहिए। नियमित अभिव्यक्ति आप चाहते है:

/^(\d+)$/ 

फिर,

if ($1 >= 1 && $1 <= 12) { 
    # valid month 
} 

यह बहुत आसान एक सांख्यिक श्रेणी मान्य करने के लिए किसी भी नियमित अभिव्यक्ति से पढ़ने के लिए है।

एक तरफ के रूप में, पर्ल एक मिलान अभिव्यक्ति के लक्ष्य के भीतर खोज द्वारा नियमित अभिव्यक्तियों का मूल्यांकन करता है। तो: एक 0 के लिए

/(0[1-9]|1[012])/ 

खोजें 1 से 9 के बाद, या एक 1 0, 1, या 2. इसके बाद उदाहरण, और कई अन्य नंबरों के लिए "202" से मेल खाएगा। एक वैकल्पिक 0 1 से 9 तक के लिए

/(0?[1-9]|1[012])/ 

खोजें, या एक 1 0 द्वारा पीछा किया, 1 या 2. तो "13" यहां से मेल खाता है, क्योंकि यह एक 1 शामिल हैं, की पहली छमाही मिलान: दूसरी ओर रेगेक्स अपने रेगुलर एक्सप्रेशन आपकी अपेक्षा के अनुसार काम करते हैं

/^(0?[1-9]|1[012])$/ 

^ और $ लंगर शुरू और स्ट्रिंग के अंत करने के लिए खोज में क्रमश: बनाने के लिए,।

+1

'/ (0 [1-9] | 1 [012]) /' 202 "से मेल नहीं खाएगा, यह" 2 ** 02 ** "के 02 भाग से मेल खाता है, लेकिन यह काफी भिन्न है। –

+3

+1: सरल संख्यात्मक सत्यापन के लिए नियमित अभिव्यक्ति ओवरकिल है। – dreamlax

+1

@ पॉल: "मैच" से आपका क्या मतलब है इस पर निर्भर करता है। इस मामले में, '202' (यानी' $ पैटर्न = ~ एम/$ माह/'के विरुद्ध * मिलान * के लिए नियमित अभिव्यक्ति का उपयोग करके, 'एम' उपसर्ग के अर्थ को ध्यान में रखते हुए) एक वास्तविक मान लौटाएगा, और कोड के लिए यह वही है जो हम नहीं चाहते हैं। हालांकि, यह केवल माता-पिता के साथ '02' भाग * कब्जा करेगा। तो यदि आप मैच का मतलब कैप्चर करने के लिए करते हैं, तो नहीं, ऐसा नहीं होगा। –

4

आप संकेत देने के लिए - महीने के नंबर "120" भी अपने संस्करण में से मेल खाता है :-)

बदलें:

my $month = "(0[1-9]|1[012])"; 

my $month = /^(0[1-9]|1[012])$/; 

और फिर इसे

के साथ और अधिक खेलने
0

यहां एक तरीका है

while(1){ 
    print "Enter in a month: "; 
    $pattern = <STDIN>; 
    chomp($pattern); 
    if ($pattern =~ /^(Q|q)$/){last;} 
    if ($pattern =~ /^[0-9]$/ || $pattern =~ /^[0-9][12]$/) { 
     print "Pattern matches\n"; 
    }else{ 
     print "try again\n"; 
    } 
} 

उत्पादन

$ perl perl.pl 
Enter in a month: 01 
Pattern matches 
Enter in a month: 000 
try again 
Enter in a month: 12 
Pattern matches 
Enter in a month: 00 
try again 
Enter in a month: 02 
Pattern matches 
Enter in a month: 13 
try again 
Enter in a month: 
+2

यह ठीक से काम नहीं करता है, 41, 42, 51, 52, आदि सभी "पैटर्न मैचों" कहते हैं। – dreamlax

2

रेगुलर एक्सप्रेशन का उपयोग न करें।

पर्ल में संदर्भ के आधार पर स्वचालित रूप से संख्या या स्ट्रिंग के रूप में मूल्यांकन करने की क्षमता है। 01-09 संख्यात्मक संदर्भ में 1-9 का मूल्यांकन करेगा। तो, आप बस एक मूल्य के लिए जाँच कर सकते हैं:

print "Enter in a month: "; 
chomp($pattern = <STDIN>); 
# We only want to print if the pattern matches 
print "Pattern matches\n" if ($pattern < 13 && $pattern > 0); 
+1

और, जब आपने सीमा की जांच की है, तो आपको इसे "% 02d" से प्रिंट कर सकते हैं यदि आपको अग्रणी शून्य की आवश्यकता है। –

-1
[^d>12|d<0] OR ^[d>12|d<0] 
+1

हो सकता है कि आप इस बारे में एक संक्षिप्त स्पष्टीकरण जोड़ सकें कि यह रेगेक्स स्पष्टीकरण के लिए कैसे काम करता है। – Amber

0

(0 [1-9] | 1 [012])

कोष्ठक रहे हैं ताकि आप यह एक और ब्लॉक के अंदर के लिए उपयोग कर सकते हैं, उदाहरण के एक पूरे yyyy-MM-DD दिनांक प्रारूप के लिए मिलान करता है, तो

स्रोत: http://www.regular-expressions.info/dates.html

1

"^(1[012]|0?[1-9])$" बेहतर होगा क्योंकि नियमित अभिव्यक्ति asse है पहले एक पहले ssed। मान लें कि आप '12' से मेल खाना चाहते हैं और आप "^(0?[1-9]|1[012])$" लिखते हैं, फिर '1' चुना जाएगा क्योंकि 0?[1-9] पहले लिया जाता है।

0

month/year परीक्षण करने के लिए:

^(0?[1-9]|1[012])\/([2-9][0-9)]{3})$ 
संबंधित मुद्दे

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