2010-07-30 44 views
2

我想在我的perl程序中使用一個字符串(例如從一個文件中讀取)作爲一段代碼。例如,我讀取一個字符串(例如$str="1..100,171,398..1000"),然後我想打印字符串表示的範圍內的所有數字。perl:使用字符串作爲代碼段

謝謝, 戴夫

+0

你究竟是什麼意思?你的文本看起來像你想要讀取一個字符串並將其作爲一個Perl語句來執行它,但是你的例子看起來像是你想要將一個字符串解析爲一些代碼的輸入。這是什麼? – Stephen 2010-07-30 16:39:11

+0

我想讀取一個字符串並將其作爲Perl語句執行。例如,我可以使用'for $ i(1..100,171,398..1000){print「$ i」}'來實現我的目標。 – 2010-07-30 16:41:43

回答

3

對於該特定情況下,看到How can I expand a string like "1..15,16" into a list of numbers?

一般而言,eval用於將字符串中的執行代碼。如果您要執行整個代碼文件,請使用do。但在考慮這個之前,請確保文件/字符串是安全的。 如果實際上「代碼」僅限於您的示例,請使用eval或do做而不是

更新:結果數字::範圍是狗慢大範圍;對於你的情況,你最好使用 - 而不是..在你的範圍內,並使用Set :: IntSpan。你問效率:使用一個數組會消耗幾兆字節的內存,但這並不是那麼糟糕。 Set :: IntSpan提供了可以使用的迭代方法,而不是僅僅生成數組,但我可能不會打擾。

+0

感謝Number :: Range!再加上另一個問題:我的範圍很大(〜500k數字,通常只有兩個數據塊,即類似1..20000,700000..1000000)。簡單地將它們打印到文件中的最有效的方法是什麼?創建一個真正的數組(如例子中)似乎不是一個好主意,或者它? – 2010-07-30 16:46:27

0

您可以使用eval在變量中執行代碼。雖然插值可能很有趣。

eval "for ($str) { print \"\$_\n\";}"

1

Number::Range使用..語法,你有,但它沒有一個迭代器。 Set::IntSpan使用-而不是..,但它確實有一個迭代器,它使得打印出來的集合沒有創建一個巨大的數組容易。

use Set::IntSpan; 

my $str = "1..100,171,398..1000"; 
$str =~ s/\.\./-/g; 
my $set = Set::IntSpan->new($str); 

for (my $i = $set->first; defined $i; $i = $set->next) { 
    print "$i\n"; # Or however you'd like to format it 
} 

在內部,Set :: IntSpan存儲範圍,所以這應該是相當高效的內存。您也可以使用spans方法獲取解析的範圍。這將需要您編寫更多的代碼,但意味着您不必爲該範圍內的每個數字執行方法調用。 Perl中的方法調用有點慢,但我不擔心它,除非上面的代碼運行時間太長。

+0

謝謝cjm。一個不錯的和優雅的解決方案,但它不適用於我,因爲Set :: IntSpan需要範圍進行排序,而我不一定(因爲某種原因)。 – 2010-07-31 06:50:06