/ / रेगेक्स पैक्ड स्पेस के साथ फिक्स लेंथ फील्ड की जांच करने के लिए - रेगेक्स

रेग्क्स पैक अंतरिक्ष के साथ तय लंबाई क्षेत्र की जांच करने के लिए - रेगेक्स

मान लें कि मेरे पास पार्स करने के लिए एक टेक्स्ट फ़ाइल है, जिसमें कुछ निश्चित लंबाई की सामग्री है:

123jackysee        45678887
456charliewong     32145644
<3><------16------><--8---> # Not part of the data.

पहले तीन अक्षर आईडी हैं, फिर 16 अक्षर उपयोगकर्ता नाम, फिर 8 अंकों का फोन नंबर।

मैं प्रत्येक पंक्ति के लिए इनपुट से मेल खाने और सत्यापित करने के लिए एक नियमित अभिव्यक्ति लिखना चाहता हूं, जिसके साथ मैं आता हूं:

(d{3})([A-Za-z ]{16})(d{8})

उपयोगकर्ता नाम में 8-16 वर्ण होने चाहिए। परंतु ([A-Za-z ]{16}) शून्य मान या स्थान से भी मेल खाएगा। मैं सोचता हूं बारे में ([A-Za-z]{8,16} {0,8}) लेकिन यह 16 से अधिक वर्णों का पता लगाएगा। कोई सुझाव?

उत्तर:

उत्तर № 1 के लिए 7

नहीं नहीं नहीं नहीं! :-)

लोग एक आरई या एसक्यूएल स्टेटमेंट में इतनी अधिक कार्यक्षमता को पैक करने का प्रयास क्यों करते हैं?

मेरा सुझाव, कुछ ऐसा करें:

  • सुनिश्चित करें कि लंबाई 27 है।
  • तीन घटकों को अलग-अलग स्ट्रिंग्स (0-2, 3-18, 19-26) में निकालें।
  • जांचें कि पहले मैच "d{3}".
  • जांचें कि दूसरा मैच "[A-Za-z]{8,} *".
  • जांचें कि तीसरा मैच "d{8}".

यदि आप चाहते हैं कि संपूर्ण चेक स्रोत कोड की एक पंक्ति पर फ़िट हो जाए, तो इसे एक फ़ंक्शन में रखें, isValidLine(), और इसे कॉल करें।

यहां तक ​​​​कि ऐसा कुछ भी चाल चलेगा:

def isValidLine(s):
if s.len() != 27 return false
return s.match("^d{3}[A-za-z]{8,} *d{8}$"):

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

मध्य क्षेत्र स्वचालित रूप से 16 वर्णों का होता हैपहली पंक्ति के कारण कुल और इस तथ्य के कारण कि अन्य दो क्षेत्र आरई में निश्चित-लंबाई वाले हैं। आरई यह भी सुनिश्चित करता है कि इसमें आठ या अधिक अक्षर हों और उसके बाद रिक्त स्थान की सही संख्या हो।

एक आरई के साथ इस तरह की चीज करने के लिए कुछ राक्षसीता होगी जैसे:

^d{3}(([A-za-z]{8} {8})
|([A-za-z]{9} {7})
|([A-za-z]{10} {6})
|([A-za-z]{11} {5})
|([A-za-z]{12}    )
|([A-za-z]{13}   )
|([A-za-z]{14}  )
|([A-za-z]{15} )
|([A-za-z]{16}))
d{8}$

आप यह सुनिश्चित करके कर सकते हैं कि यह दो पास है अलग आरईएस:

^d{3}[A-za-z]{8,} *d{8}$
^.{27}$

लेकिन, चूंकि वह आखिरी वाला केवल एक लंबा चेक है, यह इससे अलग नहीं है isValidLine() ऊपर।


जवाब के लिए 0 № 2

मैं आपके द्वारा सुझाए गए रेगेक्स का उपयोग एक छोटे से जोड़ के साथ करूंगा:

(d{3})([A-Za-z]{3,16} {0,13})(d{8})

जो उन चीजों से मेल खाएगा जिनमें a . हैगैर-व्हाट्सएप उपयोगकर्ता नाम लेकिन फिर भी स्पेस पैडिंग की अनुमति दें। एकमात्र जोड़ यह है कि आपको वर्णों की सही संख्या को सत्यापित करने के लिए प्रत्येक इनपुट की लंबाई की जांच करनी होगी।


जवाब के लिए 0 № 3

हम्म... आपके द्वारा चलाए जा रहे रेगेक्स के सटीक संस्करण के आधार पर, इस पर विचार करें:

(?P<id>d{3})(?=[A-Za-zs]{16}d)(?P<username>[A-Za-z]{8,16})s*(?P<phone>d{8})

नोट 100% सुनिश्चित करें कि यह काम करेगा, और मैंने वास्तविक स्थान के बजाय व्हाइटस्पेस एस्केप चार का उपयोग किया है - मैं केवल स्पेस कैरेक्टर से घबरा जाता हूं, लेकिन आप अधिक प्रतिबंधित होना चाहते हैं।

देखें कि क्या यह काम करता है। मैं केवल रेगेक्स के साथ मध्यवर्ती हूं, इसलिए मैं त्रुटि में हो सकता हूं।

RegEx के अपने संस्करण के लिए नामित समूह सिंटैक्स देखें a) मौजूद है और b) ऊपर उपयोग किए गए मानक I" से मेल खाता है।

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

जो मैं करने की कोशिश कर रहा हूं उसका विस्तार करने के लिए (आपकी आंखों से खून बहने के लिए खेद है, पैक्स!) उन लोगों के लिए जिनके पास बहुत सारे RegEx अनुभव नहीं हैं:

(?P<id>d{3})

यह नामित कैप्चर समूह से मेल खाने का प्रयास करेगा -"आईडी" - वह लंबाई में तीन अंक है। RegEx के अधिकांश संस्करण आपके द्वारा मिलान किए गए मानों को निकालने के लिए नामित कैप्चर समूहों का उपयोग करने देते हैं। यह आपको सत्यापन और डेटा कैप्चर करने देता है एक ही समय में. इसके लिए RegEx के विभिन्न संस्करणों में थोड़ा अलग सिंटैक्स है - चेक आउट http://www.regular-expressions.info/named.html आपके विशेष कार्यान्वयन के संबंध में अधिक जानकारी के लिए।

(?=[A-Za-zs]{16}d)

?= एक लुकहेड ऑपरेटर है।यह अगले सोलह वर्णों के लिए आगे दिखता है, और यदि वे सभी अक्षर या रिक्त स्थान वर्ण हैं और उनके बाद एक अंक है तो यह सत्य वापस आ जाएगा। लुकहेड ऑपरेटर शून्य लंबाई का है, इसलिए यह वास्तव में कुछ भी नहीं लौटाता है। आपकी RegEx स्ट्रिंग लुकहेड की शुरुआत के बिंदु से चलती रहती है। चेक आउट करें http://www.regular-expressions.info/lookaround.html लुकहेड पर अधिक विवरण के लिए।

(?P<username>[A-Za-z]{8,16})s*

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

आखिरकार,

(?P<phone>d{8})

यह आठ अंकों का फोन नंबर जांचना चाहिए।

मैं थोड़ा घबराया हुआ हूं कि यह बिल्कुल काम नहीं करेगा - RegEx का आपका संस्करण नामित समूह सिंटैक्स या लुकहेड सिंटैक्स का समर्थन नहीं कर सकता है जिसका मैं उपयोग कर रहा हूं।

मैं थोड़ा नर्वस भी हूं कि यह रेगेक्स एक खाली स्ट्रिंग से सफलतापूर्वक मेल खाएगा। रेगेक्स के विभिन्न संस्करण खाली स्ट्रिंग्स को अलग तरह से संभालते हैं।

आप इस रेगेक्स को ^ और $ के बीच एंकरिंग करने पर भी विचार कर सकते हैं ताकि यह सुनिश्चित हो सके कि आप पूरी लाइन से मेल खाते हैं, न कि केवल एक बड़ी लाइन का हिस्सा।


जवाब के लिए 0 № 4

मान लें कि आपका मतलब पर्ल रेगेक्स है और यदि आप उपयोगकर्ता नाम में "_" की अनुमति देते हैं:

perl -ne "बाहर निकलें 1 जब तक /(d{3})(w{8,16})s+(d{8})/&& लंबाई == 28"

जवाब के लिए 0 № 5

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

import sys
for line in open("file"):
line=line.strip()
# check first 3 char for digit
if not line[0:3].isdigit(): sys.exit()
# check length of username.
if len(line[3:18]) <8 or len(line[3:18]) > 16: sys.exit()
# check phone number length and whether they are digits.
if len(line[19:26]) == 8 and not line[19:26].isdigit(): sys.exit()
print line

जवाब के लिए 0 № 6

मुझे यह भी नहीं लगता कि आपको सभी कार्यक्षमताओं को एक ही रेगेक्स में पैक करने का प्रयास करना चाहिए। इसे करने का एक तरीका यहां दिया गया है:

#!/usr/bin/perl

use strict;
use warnings;

while ( <DATA> ) {
chomp;
last unless /S/;
my @fields = split;
if (
( my ($id, $name) = $fields[0] =~ /^([0-9]{3})([A-Za-z]{8,16})$/ )
and ( my ($phone) = $fields[1] =~ /^([0-9]{8})$/ )
) {
print "ID=$idnNAME=$namenPHONE=$phonen";
}
else {
warn "Invalid line: $_n";
}
}

__DATA__
123jackysee       45678887
456charliewong    32145644
678sdjkfhsdjhksadkjfhsdjjh 12345678

और यहाँ एक और तरीका है:

#!/usr/bin/perl

use strict;
use warnings;

while ( <DATA> ) {
chomp;
last unless /S/;
my ($id, $name, $phone) = unpack "A3A16A8";
if ( is_valid_id($id)
and is_valid_name($name)
and is_valid_phone($phone)
) {
print "ID=$idnNAME=$namenPHONE=$phonen";
}
else {
warn "Invalid line: $_n";
}
}

sub is_valid_id    { ($_[0]) = ($_[0] =~ /^([0-9]{3})$/) }

sub is_valid_name  { ($_[0]) = ($_[0] =~ /^([A-Za-z]{8,16})s*$/) }

sub is_valid_phone { ($_[0]) = ($_[0] =~ /^([0-9]{8})$/) }

__DATA__
123jackysee        45678887
456charliewong     32145644
678sdjkfhsdjhksadkjfhsdjjh 12345678

सामान्यीकरण:

#!/usr/bin/perl

use strict;
use warnings;

my %validators = (
id    => make_validator( qr/^([0-9]{3})$/ ),
name  => make_validator( qr/^([A-Za-z]{8,16})s*$/ ),
phone => make_validator( qr/^([0-9]{8})$/ ),
);

INPUT:
while ( <DATA> ) {
chomp;
last unless /S/;
my %fields;
@fields{qw(id name phone)} = unpack "A3A16A8";

for my $field ( keys %fields ) {
unless ( $validators{$field}->($fields{$field}) ) {
warn "Invalid line: $_n";
next INPUT;
}
}

print "$_ : $fields{$_}n" for qw(id name phone);
}

sub make_validator {
my ($re) = @_;
return sub { ($_[0]) = ($_[0] =~ $re) };
}

__DATA__
123jackysee        45678887
456charliewong     32145644
678sdjkfhsdjhksadkjfhsdjjh 12345678

उत्तर के लिए 0 № 7

आप लुकहेड का उपयोग कर सकते हैं: ^(d{3})((?=[a-zA-Z]{8,})([a-zA-Z ]{16}))(d{8})$

परिक्षण:

१२३जैकीसी ४५६७८८८७मैच 456चार्लीवॉन्ग 32145644 मैच 789jop 12345678 कोई मेल नहीं - उपयोगकर्ता नाम बहुत छोटा है 999abcdefghijabcde12345678 कोई मेल नहीं - उपयोगकर्ता नाम "कॉलम" 16 वर्णों से कम है 999abcdefghijabcdef12345678 मैच 999abcdefghijabcdefg12345678 कोई मेल नहीं - उपयोगकर्ता नाम कॉलम 16 वर्णों से अधिक है