2012-02-06 11 views
6

द्वारा सीमित एक ही पंक्ति में एक पैटर्न से कई बार मिलान करें, मैं इस के समान, लेकिन समान प्रश्न नहीं ढूंढ पा रहा हूं। अज्ञात वर्णों द्वारा सीमित एक ही पंक्ति में मैं एक रेगेक्स पैटर्न को कई बार कैसे मेल करूं?पर्ल, अज्ञात वर्णों

उदाहरण के लिए, कहें कि मैं पैटर्न HEY से मेल खाना चाहता हूं। मैं निम्न में से सभी को पहचान करना चाहते हैं:

अरे

हे हे

HEYxjfkdsjfkajHEY

इसलिए मैं 5 Heys वहाँ गिनती होगी। तो यहाँ मेरी कार्यक्रम है, जो सब कुछ है, लेकिन पिछले एक के लिए काम करता है:

open (FH, $ARGV[0]); 
while(<FH>) 
{ 
    foreach $w (split) 
    { 
     if ($w =~ m/HEY/g) 
     { 
      $count++; 
     } 
    } 
} 

तो मेरे सवाल का मैं कैसे में दिखाया गया है की तरह इतना है कि मैं अज्ञात विन्यास में अजीब वर्ण (द्वारा सीमांकित पैटर्न को पहचान सकते हैं कि foreach पाश की जगह है ऊपर उदाहरण)?

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

अब तक महान प्रतिक्रिया के लिए धन्यवाद। मुझे अभी एहसास हुआ कि मुझे एक और चीज चाहिए, जिसे मैंने नीचे एक टिप्पणी में रखा था।

एक सवाल हालांकि: क्या मिलान किए गए कार्य को भी सहेजने का कोई तरीका है? मेरे मामले में की तरह तो, वहाँ $ w संदर्भित करने के लिए किसी भी तरह से है (जैसे कि अगर regex और अधिक जटिल था, और मैं घटनाओं की संख्या के साथ एक हैश में संग्रहीत करना चाहता था) अगर मैं एक मेल खा रहा था

तो असली रेगेक्स (अल्फान्यूमेरिक वर्णों का अनुक्रम कहें) और इसे हैश में सहेजना चाहता था।

उत्तर

11

एक तरीका है स्ट्रिंग के सभी मैचों को कैप्चर करना और देखें कि आपको कितने मिलते हैं। इसलिए जैसा:

open (FH, $ARGV[0]); 
while(my $w = <FH>) { 
    my @matches = $w =~ m/(HEY)/g; 
    my $count = scalar(@matches); 
    print "$count\t$w\n"; 
} 

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

हाँ, वहाँ है! बस सभी मैचों में पाश, और हैश पर संख्या में भी वृद्धि करने के लिए कब्जा चर का उपयोग:

my %hash; 
open (FH, $ARGV[0]); 
while (my $w = <FH>) { 
    foreach ($w =~ /(HEY)/g) { 
     $hash{$1}++; 
    } 
} 
+0

हे, मदद के लिए धन्यवाद। मुझे वास्तव में आपके सामान को दो तरीकों से काम करने के लिए संशोधित करना पड़ा: सबसे पहले, मैं अपने जीवन के लिए पहले भाग के लिए अपना समाधान प्राप्त नहीं कर सका, इसलिए मैंने उस के लिए वेस के दृष्टिकोण का उपयोग किया (दो जबकि लूप)। इसके अलावा, मैं सिर्फ यह ध्यान रखना चाहता था कि समूहों के समूह के साथ regexes() पूरे regex के आसपास की आवश्यकता है, ताकि आप आवश्यक कुल के टुकड़ों के साथ एक हैश नहीं मिलता है। हालांकि धन्यवाद! – varatis

+1

एकाधिक समूह से निपटने पर आपका मित्र गैर-कैप्चरिंग समूह है जिसे प्रश्न चिह्न-कॉलन '(? :)' के साथ संशोधित किया गया है। – masaers

5

समस्या यह है क्या तुम सच में विभाजित कॉल करने के लिए नहीं करना चाहते हैं()। यह चीजों को शब्दों में विभाजित करता है, और आप ध्यान देंगे कि आपकी आखिरी पंक्ति में केवल एक "शब्द" है (हालांकि आपको इसे शब्दकोश में नहीं मिलेगा)। एक शब्द सफेद अंतरिक्ष से घिरा हुआ है और इस प्रकार बस "सबकुछ लेकिन सफेद जगह" है।

आप जो वास्तव में चाहते हैं वह प्रत्येक पंक्ति को गिनने वाली प्रत्येक पंक्ति को देखना जारी रखना है, जहां से आप हर बार छोड़ देते हैं। कौन सा की आवश्यकता है/जी अंत में लेकिन देख रखने के लिए:

while(<>) 
{ 
     while (/HEY/g) 
     { 
      $count++; 
     } 
} 

print "$count\n"; 

वहाँ, ज़ाहिर है, एक से अधिक तरीके यह करने के लिए है, लेकिन यह आपके उदाहरण के करीब चिपक। अन्य लोग भी अन्य अद्भुत उदाहरण पोस्ट करेंगे। उन सभी से सीखो!

+0

अरे, यह बहुत अच्छा है! मैंने अभी तक इसे लागू नहीं किया है, लेकिन ऐसा लगता है कि इसे काम करना चाहिए। हालांकि एक प्रश्न: क्या मिलान किए गए कार्य को भी सहेजने का कोई तरीका है? तो मेरे मामले में, क्या $ डब्ल्यू का संदर्भ देने का कोई तरीका है (कहें कि रेगेक्स अधिक जटिल था, और मैं इसे घटनाओं की संख्या के साथ हैश में स्टोर करना चाहता था) – varatis

+0

हां यह बहुत संभव है। मेरा संपादित उत्तर देखें। – masaers

0

उपर्युक्त उत्तरों में से कोई भी मेरी इसी समस्या के लिए काम नहीं करता है। $ 1 बदलना प्रतीत नहीं होता है (perl 5.16.3) तो $ हैश {$ 1} ++ केवल पहले मैच n बार गिना जाएगा।

प्रत्येक मैच प्राप्त करने के लिए, फ़ोरैच को एक स्थानीय चर निर्दिष्ट करने की आवश्यकता होती है, जिसमें मिलान चर शामिल होगा। यहां एक छोटी सी स्क्रिप्ट है जो प्रत्येक घटना (संख्या) से मेल खाती है और प्रिंट करेगी।

#!/usr/bin/perl -w                              
use strict; 
use warnings FATAL=>'all'; 

my (%procs); 
while (<>) { 

    foreach my $proc ($_ =~ m/\((\d+)\)/g) { 
     $procs{$proc}++; 
    } 

} 

print join("\n",keys %procs) . "\n"; 

मैं इसे उपयोग कर रहा हूँ इस तरह:

pstree -p | perl extract_numbers.pl | xargs -n 1 echo 

(कि पाइप लाइन में कुछ प्रासंगिक फ़िल्टर के साथ छोड़कर)। किसी भी पैटर्न कैप्चर को भी काम करना चाहिए।

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