2017-02-09 23 views
1

我想知道在perl正則表達式中使用常量。我想要做類似的東西:Perl在正則表達式中使用常量

use constant FOO => "foo" 
use constant BAR => "bar" 

$somvar =~ s/prefix1_FOO/prefix2_BAR/g; 
當然

,在那裏,FOO解析爲三個字母FOO而不是擴大到常數。

我在網上看,有人建議使用${\FOO}@{[FOO]}別人提到(?{FOO})。我想知道是否有人能說出哪些是正確的,以及是否有任何優勢。或者,只使用非常量變量會更好嗎? (對我來說性能是一個因素)。

回答

4

的,你告訴的問題是由於這些常量是裸字(在編譯時建)使用此模塊定義

常量不能插值到像變量的字符串。

在 「當前實行」(v5.24文檔)它們可以內聯子程序。請參閱constant編譯指示。

這個問題可以通過使用一個模塊來解決,像Const::Fast

use Const::Fast; 

const my $foo => 'FOO'; 
const my $bar => 'BAR'; 

my $var = 'prefix1_FOO_more'; 

$var =~ s/prefix1_$foo/prefix2_$bar/g; 

現在他們將要插入。請注意,更復雜的替換可能需要/e

這些是在運行時構建的,因此您可以爲它們分配表達式的結果。特別是,你可以使用qr operator,例如

const my $patt => qr/foo/i; # case-insensitive 

qr是構建正則表達式模式的推薦方式。性能增益通常很小,但是你得到一個常數,這是一個適當的正則表達式(並且可以像這樣構建)。

我使用這個模塊,並沒有遇到問題。我很樂意推薦它。請參閱recent article並詳細討論兩者。以下是其他許多選項的review

1

據PerlMonk,你最好創建一個已經插字符串,如果你關心性能:

use constant PATTERN => 'def'; 
my $regex = qr/${\(PATTERN)}/; #options such as /m can go here. 
if ($string =~ regex) { ... } 

這裏是鏈接到whole discussion

5

在變量上使用常量的原因並不多。它沒有太大區別 - perl無論如何都會編譯一個正則表達式。

例如:

#!/usr/bin/perl 

use warnings; 
use strict; 
use Benchmark qw(:all); 

use constant FOO => "foo"; 
use constant BAR => "bar"; 

my $FOO_VAR = 'foo'; 
my $BAR_VAR = 'bar'; 

sub pattern_replace_const { 
    my $somvar = "prefix1_foo test"; 
    $somvar =~ s/prefix1_${\FOO}/prefix2_${\BAR}/g; 
} 

sub pattern_replace_var { 
    my $somvar = "prefix1_foo test"; 
    $somvar =~ s/prefix1_$FOO_VAR/prefix2_$BAR_VAR/g; 
} 

cmpthese(
    1_000_000, 
    { 'const' => \&pattern_replace_const, 
     'var' => \&pattern_replace_var 
    } 
); 

給出:

  Rate const var 
const 917095/s -- -1% 
var 923702/s 1% -- 

真的不夠的,在它的擔心。

但是它可能是值得一提的 - 你可以編譯qr//正則表達式,做這樣的說法,這 - 提供的RE是靜態的 - 可能會提高性能(但它可能沒有,因爲Perl 可以檢測靜態正則表達式,而這是否本身

Rate  var const compiled 
var  910498/s  --  -2%  -9% 
const 933097/s  2%  --  -7% 
compiled 998502/s  10%  7%  -- 

有了這樣的代碼:

my $compiled_regex = qr/prefix1_$FOO_VAR/; 
sub compiled_regex { 
    my $somvar = "prefix1_foo test"; 
    $somvar =~ s/$compiled_regex/prefix2_$BAR_VAR/g; 
} 

老實說,雖然 - 這是一個微型優化的正則表達式引擎是比較快你的代碼,所以不用擔心。它。如果性能對您的代碼至關重要,那麼正確的處理方式是先寫編寫代碼,然後然後配置文件查找熱點進行優化。

+3

我認爲常量的重點不在於它們可能比變量更快,而是它們是*常量*。 – Borodin

+0

在我的特殊情況下,我使用的值確實是不變的。由於這個原因,我正在考慮轉向常數以及潛在的性能優勢。 – user2766918