2009-06-19 9 views
5

मेरे पास एक पर्ल एप्लिकेशन है जो कमांड लाइन से इनपुट को लेता है:मैं संख्याओं की सूची में "1..15,16" जैसे स्ट्रिंग का विस्तार कैसे कर सकता हूं?

application --fields 1-6,8 

मुझे कमांड लाइन पर उपयोगकर्ता द्वारा अनुरोध किए गए फ़ील्ड को प्रदर्शित करने की आवश्यकता है।

मैंने '-' को '..' के साथ प्रतिस्थापित करने के बारे में सोचा ताकि मैं उन्हें सरणी में संग्रहीत कर सकूं।

$str = "1..15,16" ; 
@arr2 = ($str) ; 
@arr = (1..15,16) ; 
print "@arr\n" ; 
print "@arr2\n" ; 

यहां समस्या यह है कि @arr ठीक काम करता है (जैसा कि यह होना चाहिए) लेकिन @ arr2 में संपूर्ण स्ट्रिंग सरणी तत्वों के रूप में विस्तारित नहीं होती है।

मैंने भागने के दृश्यों का उपयोग करने की कोशिश की है लेकिन कोई भाग्य नहीं है।

क्या यह इस तरह से किया जा सकता है?

उत्तर

26

यदि यह उपयोगकर्ता इनपुट है, तो यदि आपके पास कोई सुरक्षा चिंता है तो स्ट्रिंग eval का उपयोग न करें। .. के बजाय -

eval { @arr2 = Number::Range->new($str)->range; 1 } or your_error_handling 

वहाँ भी Set::IntSpan है, जो का उपयोग करता है::

use Set::IntSpan; 

$str = "1-15,16"; 
@arr2 = Set::IntSpan->new($str)->elements; 

बजाय Number::Range उपयोग करके देखें:

use Number::Range; 

$str = "1..15,16" ; 
@arr2 = Number::Range->new($str)->range; 
print for @arr2; 

गलत रेंज पर मर रहा से बचने के लिए करते हैं

लेकिन इसके लिए श्रेणियों को क्रम में और गैर-ओवरलैपिंग की आवश्यकता होती है (यह .newsrc फ़ाइलों पर उपयोग के लिए लिखा गया था, अगर कोई याद करता है कि वे क्या हैं)। यह अनंत श्रेणियों को भी अनुमति देता है (जहां स्ट्रिंग शुरू होती है - संख्या या संख्या -), जो तत्व विधि क्रोक हो जाएगी।

+4

+1 की आवश्यकता है। "इसे सही करना" हमेशा eval करने के लिए बेहतर है। बहुत कम दुष्प्रभाव। – jrockway

+0

मैं पहले नंबर :: रेंज में कभी नहीं आया हूं। मैंने भविष्य में उपयोग के लिए इसे दायर कर दिया है। मुझे इसके बारे में जागरूक करने के लिए धन्यवाद! –

+0

यदि आप उपयोगकर्ता इनपुट लेते हैं, तो आपका ऐप 1.000000000 तक उड़ाएगा, जब तक आपके पास लगभग 8 जीबी रैम न हो। संख्या :: श्रेणी-> आकार() अभी इसे रोकने के लिए बेकार है क्योंकि यह आकार को समझने के लिए पूरी श्रृंखला उत्पन्न करता है। –

-2

उपयोग विभाजन:

@parts = split(/\,/, $fields); 

print $parts[0]; 
1-6 
print $parts[1]; 
8 

तुम बस एक सरणी में ',' स्ट्रिंग वाली नहीं डाल सकते हैं, और (तत्वों को चालू करने के लिए यह उम्मीद करता है, तो आप कुछ पर्ल काला जादू का उपयोग करें, लेकिन हम जीत को छोड़कर उसमें यहां न जाएं)

लेकिन रेगेक्स और विभाजन आपके मित्र हैं।

+0

जो मैं समझता हूं ...
वास्तव में जो मैं चाहता हूं वह अंततः @parts में होना चाहिए (1,2,3,4,5,6,8)
जो बराबर है (1..6,8) – sud03r

0
@arr2 = (eval $str) ; 

काम करता है, बेशक आपको eval() के साथ बहुत सावधान रहना होगा।

+0

thanx ... मुझे बस उस – sud03r

-1

आप eval इस्तेमाल कर सकते हैं:

$str = "1..15,16" ; 
@arr2 = (eval $str) ; 
@arr = (1..15,16) ; 
print "@arr\n" ; 
print "@arr2\n" ; 

हालांकि अगर यह उपयोगकर्ता इनपुट है, तो आप शायद पहले इनपुट स्ट्रिंग पर कुछ सत्यापन करना है, यह सुनिश्चित करना चाहते जाएगा कि वे नहीं इनपुट कुछ भी कुशल है।

1

आप @arr2 = eval($str); के बारे में सोच रहे हैं क्योंकि आप इनपुट ले रहे हैं और इसका मूल्यांकन कर रहे हैं, आपको सावधान रहना होगा। आपको शायद @arr2 = eval($str) if ($str =~ m/^[0-9.,]+$/)

पीएस होना चाहिए मुझे नंबर :: रेंज पैकेज के बारे में पता नहीं था, लेकिन यह awesome है। संख्या :: श्रेणी ftw।

1

मुझे बिट :: वेक्टर :: to_Enum के आउटपुट से निपटने में एक ही समस्या थी।

$range_string =~ s/\b(\d+)-(\d+)\b/expand_range($1,$2)/eg; 

तो मेरी फाइल में भी:

sub expand_range 
{ 
    return join(",",($_[0] .. $_[1])); 
} 

तो "1,3,5-7,9,12-15" "1,3,5 में बदल जाता है मैं ऐसा करके इसे हल , 6,7,9,12,13,14,15 "।

मैंने एस /// के दूसरे भाग में उस विस्तार को रखने के लिए वास्तव में कड़ी मेहनत की, इसलिए मुझे उस अतिरिक्त कार्य की आवश्यकता नहीं होगी, लेकिन मैं इसे काम नहीं कर सका। मुझे यह पसंद है क्योंकि संख्या :: रेंज काम करेगी, इस तरह मुझे किसी अन्य मॉड्यूल को खींचने की ज़रूरत नहीं है जो तुच्छ होना चाहिए।

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

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