2013-03-30 92 views
1

我一直在尋找一個解決方案,我的問題和哈希似乎是閱讀幾篇文章後的答案,但我不確定如何實現這個我的要求,任何人都可以建議如何甚至更好的選擇?引用變量中的變量 - 哈希?

在我的代碼中,變量$host正在根據數據庫中的值進行設置。我遍歷這些值,每次更改$host的值。

我想丟棄一些類型的主機名,並確定哪些主機丟棄我讀取在一個用戶可配置的文件,該文件包含該排除的Perl正則表達式。即配置文件中有一行

EXCLUDE=\d+DAT\d+,\d+INF\d+ 

我當時想建立Perl的正則表達式匹配(邏輯OR),即

if ($host =~ m/\d+DAT\d+/ || $host =~ m/\d+INF\d+/) { 
    # do something 
} 

目前我的代碼是硬接線如在上面的例子,但是如何在讀取配置文件後動態構造Perl正則表達式?

我已經讀取配置文件到一個數組,並將從那裏開始。上面的代碼需要落得這樣的:

if ($exclude clause) { 
    # do something 
} 

這是我如何着手實現從陣列讀取:

for ($i = 1; $i < @conf; $i++) { 
    $exclude_clause .= "$host =~/" . @conf[$i] . "/ || "; 
} 
$exclude_clause =~ s/ \|\| $//; 

問題是$exclude_clause中引用$host。除了$host之外,我的正則表達式字符串是內置的。

+0

到底是什麼問題?這是你試圖運行的實際代碼嗎? – lmsteffan

回答

0

我會建議一種不需要你建立一個大的正則表達式字符串然後進行評估的方法。相反,如果使用List::MoreUtils模塊的any函數(它接受一個代碼塊)對列表中的每個成員進行求值,並且一旦該塊對列表中的至少一個條目返回true,則返回true。例如:

use List::MoreUtils qw{ any }; 

if (any { $host =~ $_ } @conf) { 
    # do something 
} 

在傳遞給any碼塊,臨時變量$_包含列表中的當前條目。這樣可以避免首先構建正則表達式。

+0

這聽起來是一個整潔的解決方案,只是爲了確認 - 如果我的@conf數組值是\ d + DAT \ d +(位置1)和\ d + INF \ d +(pos2)等等,那麼每個測試都會進行正則表達式匹配反對$主機&應該任何匹配然後#做一些事情。 – user2008555

+0

我剛剛嘗試運行上述建議,我收到錯誤「無法調用方法」任何「沒有包或對象引用........線193」 - 行193如下所示: - 如果(任何{$主機=〜M/$ _ /} @conf){ #do東西 } 我已經安裝列表:: MoreUtils,這是在我的代碼 「使用名單:: MoreUtils」 有什麼建議嗎? Mark – user2008555

+0

我應該寫'use List :: MoreUtils qw {any};'。上面更新了我的答案。 –

0

我認爲你應該在配置文件中存儲完整的正則表達式,但如果需要的話,它可以是一組逗號分隔的替代方案。

你會使用qr//結構來構建正則表達式:

my $exc1 = "\d+DAT\d+"; # Read from configuration file 
my $ecc2 = "\d+INF\d+"; 

my $rex1 = qr/$exc1/; 
my $rex2 = qr/$exc2/; 

...populate $host... 

if ($host =~ $rex1 || $host =~ $rex2) 
{ 
    ...exclude $host... 
} 
else 
{ 
    ...include $host... 
} 

或者,您可以建立一個單一的正則表達式:

my $exc1 = "\d+DAT\d+"; # Read from configuration file 
my $ecc2 = "\d+INF\d+"; 

my $rex = qr/$exc1|$exc2/; 

...populate $host... 

if ($host =~ $rex) 
{ 
    ...exclude $host... 
} 
else 
{ 
    ...include $host... 
} 

單正則表達式可以從許多替代排除正則表達式來建片段,如你所願。當然,如果該文件中的值是:

EXCLUDE=\d+DAT\d+|\d+INF\d+ 

那麼你的代碼,來簡化一次,假設正則表達式的字符串被讀入$exc

my $exc = "\d+DAT\d+|\d+INF\d+"; # Read from file 
my $rex = qr/$exc/; 

...populate $host... 

if ($host =~ $rex) 
{ 
    ...exclude $host... 
} 
else 
{ 
    ...include $host... 
}