2008-09-17 10 views
30

मुझे एक ऐसा फ़ंक्शन लिखना होगा जो स्ट्रिंग और रेगेक्स प्राप्त करे। मुझे यह जांचने की ज़रूरत है कि कोई मैच है या नहीं और मैच के प्रारंभ और अंत स्थान को वापस कर दें। (रेगेक्स पहले से ही qr// द्वारा संकलित किया गया था।)पर्ल में रेगेक्स मैच का स्थान मैं कैसे ढूंढ सकता हूं?

फ़ंक्शन को "वैश्विक" ध्वज भी मिल सकता है और फिर मुझे सभी मैचों के जोड़े (प्रारंभ, अंत) जोड़े को वापस करने की आवश्यकता है।

मैं रेगेक्स को नहीं बदल सकता, इसके आसपास () भी नहीं जोड़ सकता क्योंकि उपयोगकर्ता () और \1 का उपयोग कर सकता है। शायद मैं (?:) का उपयोग कर सकता हूं।

उदाहरण: वैश्विक मामले में "ababab" और regex qr/ab/ दिया गया है, मुझे 3 जोड़े (प्रारंभ, अंत) वापस पाने की आवश्यकता है।

+0

लियोन की व्याख्या को स्वयं बनाकर आप यह स्पष्ट करना चाहते हैं कि ध्वज/जी संशोधक या किसी भी() रेगेक्स में कैप्चर करता है या नहीं। –

उत्तर

10

pos function आपको मैच की स्थिति देता है। यदि आप अपने रेगेक्स को कोष्ठक में डालते हैं तो आप length $1 का उपयोग करके लंबाई (और इस प्रकार अंत) प्राप्त कर सकते हैं। इस

sub match_positions { 
    my ($regex, $string) = @_; 
    return if not $string =~ /($regex)/; 
    return (pos($string), pos($string) + length $1); 
} 
sub all_match_positions { 
    my ($regex, $string) = @_; 
    my @ret; 
    while ($string =~ /($regex)/g) { 
     push @ret, [pos($string), pos($string) + length $1]; 
    } 
    return @ret 
} 
+1

यह पूरी तरह से गलत लगता है। स्थिति के बजाय, अन्य मामले में, all_match_positions में स्थिति ($ स्ट्रिंग) का उपयोग करें, match_positions यह सब – Aftershock

+0

@Aftershock पर काम नहीं करता है: आप पूरी तरह से सही हो! ऊप्स! –

0

की तरह तुम भी, तो बहिष्कृत $ `चर का उपयोग कर सकते हैं अगर आप अपने प्रोग्राम में सभी आर ई धीमी पर अमल करने के लिए तैयार हैं। Perlvar से:

$‘  The string preceding whatever was matched by the last successful pattern match (not 
      counting any matches hidden within a BLOCK or eval enclosed by the current BLOCK). 
      (Mnemonic: "`" often precedes a quoted string.) This variable is read-only. 

      The use of this variable anywhere in a program imposes a considerable performance penalty 
      on all regular expression matches. See "BUGS". 
17

मेरी पिछली पोस्ट को भूल जाओ, मुझे एक बेहतर विचार है।

sub match_positions { 
    my ($regex, $string) = @_; 
    return if not $string =~ /$regex/; 
    return ($-[0], $+[0]); 
} 
sub match_all_positions { 
    my ($regex, $string) = @_; 
    my @ret; 
    while ($string =~ /$regex/g) { 
     push @ret, [ $-[0], $+[0] ]; 
    } 
    return @ret 
} 

यह तकनीक किसी भी तरह से रेगेक्स को नहीं बदलेगी।

जोड़ने के लिए संपादित: perlvar से $ 1 .. $ 9 पर उद्धरण के लिए। "ये चर सभी पढ़ने-योग्य और गतिशील रूप से वर्तमान ब्लॉक पर स्कॉप्ड हैं।" दूसरे शब्दों में, यदि आप $ 1 का उपयोग करना चाहते हैं .. $ 9, तो आप मिलान करने के लिए सबराउटिन का उपयोग नहीं कर सकते हैं।

+0

मुझे लगता है कि यह अभी भी काम नहीं करेगा अगर regex – szabgab

+0

हाँ में हैं, हाँ, मेरा ईटीए देखें। –

+0

आप एक सबरूटीन) का उपयोग कर सकते मैच करने के लिए है, लेकिन आप substr (उपयोग करने के लिए कैप्चर आप होगा चाहते हैं, @ -, और @ + मैचों निकालें और उन्हें उपयोगकर्ता पर लौटने के लिए। –

70

अंतर्निहित चर @- और @+ अंतिम सफल मैच के क्रमशः प्रारंभ और समाप्ति स्थिति को पकड़ें। $-[0] और $+[0] पूरे पैटर्न से मेल खाते हैं, जबकि $-[N] और $+[N]$N ($1, $2, आदि) से मेल खाते हैं।

+11

ये जादू चर मुझे अजगर से आ रही क्रोध करना चाहते हैं; उन्हें [perl re docs] (http://perldoc.perl.org/perlre.html) में एक बार भी संदर्भित नहीं किया जाता है। –

+5

perldoc perlvar ;-) – Phil

+3

ध्यान दें कि $ + [0] आदि ("अंत पदों") चरित्र के सूचकांक * निम्नलिखित * मैच देते हैं, नहीं मैच के ही अंतिम वर्ण। – TextGeek

0
#!/usr/bin/perl 

# search the postions for the CpGs in human genome 

sub match_positions { 
    my ($regex, $string) = @_; 
    return if not $string =~ /($regex)/; 
    return (pos($string), pos($string) + length $1); 
} 
sub all_match_positions { 
    my ($regex, $string) = @_; 
    my @ret; 
    while ($string =~ /($regex)/g) { 
     push @ret, [(pos($string)-length $1),pos($string)-1]; 
    } 
    return @ret 
} 

my $regex='CG'; 
my $string="ACGACGCGCGCG"; 
my $cgap=3;  
my @pos=all_match_positions($regex,$string); 

my @hgcg; 

foreach my $pos(@pos){ 
    push @hgcg,@$pos[1]; 
} 

foreach my $i(0..($#hgcg-$cgap+1)){ 
my $len=$hgcg[$i+$cgap-1]-$hgcg[$i]+2; 
print "$len\n"; 
} 
संबंधित मुद्दे