2011-03-03 15 views
18

मुझे आश्चर्य है कि क्या पर्ल के पास एक विशेष रेगेक्स से मेल खाने वाली कुंजी के साथ हैश तत्व के अस्तित्व की जांच करने का एक अंतर्निहित तरीका है। उदाहरण के लिए:पर्ल: नियमित अभिव्यक्ति के लिए हैश कुंजी मिलान करना

my %h = ('twelve' => 12, 'thirteen' => 13, 'fourteen' => 14); 

मैं अगर वहाँ यह करने के लिए किसी भी तरह से है सोच रहा हूँ:

print "We have 12\n" if exists $h{twelve}; 
print "We have some teens\n" if exists $h{/.*teen$/}; 
+2

यदि आपके पास 'किशोर $' '*' अनिवार्य है। – Axeman

उत्तर

24

smart match operator यह करता है (पर्ल v5.10 के बाद उपलब्ध)।

$a  $b  Type of Match Implied Matching Code 
====== =====  ===================== ============= 
... 
Regex Hash  hash key grep   grep /$a/, keys %$b 
... 

नमूना उपयोग:

# print if any key in %h ends in "teen" 
print "We have some teens\n" if /.*teen$/ ~~ %h; 
+1

ध्यान दें कि यह ऑपरेटर प्रवाह की स्थिति में रहा है और इसे पर्ल 5.18 के रूप में "प्रयोगात्मक" समझा गया है (चेतावनियों को कहीं भी इस्तेमाल किया जा रहा है)। http://stackoverflow.com/questions/16927024/perl-5-20-and-the-fate-of-smartmatch-and-given-when/ – sundar

+1

यह मेरे लिए ठीक है। – user1807271

4

नहीं है कोई अंतर्निहित तरीका है, लेकिन वहाँ CPAN पर Tie::Hash::Regex है।

6

हाँ, यह कहा जाता है:

use List::Util qw<first>; 

# Your regex does not compile perhaps you mean /teen$/ 
my $value = $hash{ (first { m/teen/ } keys %hash) || '' }; 

(स्मार्ट मैच से पहले, वह यह है कि स्मार्ट मैच के लिए भीड़ का जवाब देखें।।)

आप कुंजी को भी सॉर्ट कर सकता है:

my $value = $hash{ (first { m/teen/ } sort keys %hash) || '' }; 

मैं एक "ऑपरेशन" में इस फ्रीज होगा:

use Scalar::Util qw<reftype>; 

sub values_for_keys_like (\[%$]$) { 
    my $ref = reftype($_[0]) eq 'HASH' ? $_[0] : $$_[0]; 
    return unless my @keys = keys %$ref; 

    my $regex = shift; 
    # allow strings 
    $regex = qr/$regex/ unless my $typ = ref($regex); 
    # allow regex or just plain ol' filter functions. 
    my $test = $typ eq 'CODE' ? $regex : sub { return unless m/$regex/; 1 }; 

    if (wantarray) { 
     return unless my @k = grep { defined $test->($_) } @keys; 
     return @$ref{ @k }; 
    } 
    else { 
     return unless my $key = first { defined $test->($_) } @keys; 
     return $ref->{ $key }; 
    } 
} 

और तुम इतना है कि यह इस्तेमाल कर सकते हैं:

my $key = values_for_keys_like(%hash => qr/teen/); 

या

my $key = values_for_keys_like($base->{level_two}{level_three} => qr/teen/); 
+0

'सॉर्ट'? एह? चाबियाँ सॉर्ट करने का कोई कारण नहीं है यदि आप सिर्फ परीक्षण कर रहे हैं कि कोई मिलान मौजूद है या नहीं। बस 'पहले {एम/किशोर $ /} कुंजी% हैश' बेहतर है। –

+0

@ डेव शेरहमान: सामान्य रूप से एसओ में, सामान्य प्रश्न है और उपयोगकर्ता द्वारा देखे जाने वाले विशेष एप्लिकेशन का उपयोग किया जाता है। सामान्य सवाल है "नियमित अभिव्यक्ति के लिए हैश कुंजी मिलान करना"। 'पहला' 'किसी भी 'अवधारणा का कार्यान्वयन है - लेकिन इसमें अन्य प्रभाव शामिल हैं: पहला * कैसे? * मैं विशिष्ट एप्लिकेशन से अधिक कवर करना चाहता हूं। – Axeman

+2

मैं * किसी भी * स्थिति को देखने में विफल रहता हूं जिसमें सॉर्टिंग प्रश्न पर लागू होती है "क्या कोई मैच है?"। चाहे कोई मिलान मौजूद है या नहीं, आदेश से स्वतंत्र है, इस प्रकार आदेश अप्रासंगिक है। सॉर्टिंग का एकमात्र प्रभाव एक विशिष्ट क्रम लगाने के लिए है, लेकिन आदेश अप्रासंगिक है, इसलिए सॉर्टिंग केवल किसी उद्देश्य के लिए संसाधनों (समय/मेमोरी) का उपयोग नहीं करता है। यहां सवाल 'किसी भी' अवधारणा के बारे में पूछ रहा है, आदेश से स्वतंत्र; 'पहला' पूरी तरह उपयुक्त है क्योंकि 'सूची :: उपयोग' कोई 'कोई' फ़ंक्शन प्रदान नहीं करता है। –

12

अन्य उत्तर के अलावा यहां आप पेर्ल के grep के साथ भी ऐसा कर सकते हैं:

print "We have some teens\n" if grep {/.*teen/} keys %h; 
संबंधित मुद्दे