2014-09-20 22 views
1

我的問題是:如何在Perl程序中輕鬆訪問模式匹配數組? (我知道有解決方案涉及split或/.../g,但我特別要求一個簡單的方法來訪問變量$ 1,$ 2,$ 3,...在Perl程序中輕鬆訪問模式匹配捕獲數組

(我認爲應該有一個數組,類似於@和@ +,但我找不到)

這是我到目前爲止(解決方案A涉及substr($ line,$ - [$ ],$ + [$ ] - $ - [$ ])和溶液B包括EVAL 「\ $$」),但我寧願訪問的變量$ 1,$ 2,$ 3直接作爲數組:

use strict; 
use warnings; 

my $line = (join '', map { chr($_ + 64) } 1..26) x 10; 

my $rstr = ''; 
$rstr .= '('.('.' x (rand(3) + 2)).')' for 1..rand(15) + 3; 

unless ($line =~ m{\A $rstr}xms) { 
    die "No match"; 
} 

print $rstr, "\n"; 

for (1..$#-) { 
    printf "A> %3d. -> pos%3d -%3d = '%s'\n", $_, 
     $-[$_], $+[$_] - 1, substr($line, $-[$_], $+[$_] - $-[$_]); 
} 

print "\n"; 

for (1..$#-) { 
    printf "B> %3d. -> pos%3d -%3d = '%s'\n", $_, 
     $-[$_], $+[$_] - 1, eval "\$$_"; 
} 
+0

什麼是 「一個模式匹配的數組」 是什麼意思?也許你可以給出一個清楚的例子,說明你正在做什麼以及爲什麼你不能使用'$ 1','$ 2'等等,或者'm /../ g'返回的數組。 – 2014-09-20 15:22:01

回答

6

在表達式的Perl結果可能取決於其調用上下文(例如,標量上下文或數組上下文,或無效上下文)。如果將operator =〜的值賦給數組,該數組將包含所需的值。

@arr = ('abcd' =~ /(.)(.)(.)(.)/); 

這裏@arr將僅包含($1, $2, $3, $4),即('a', 'b', 'c', 'd')

-1

正如@atycnth已經指出的,您搜索的數組是由列表上下文中的正則表達式匹配返回的。

這裏是你的代碼擴展用這種方法補充說:

use strict; 
use warnings; 

# Fake Data 
my $fake_data = join '', ('A' .. 'Z') x 10; 

# Build a random Regular Expression 
my $pattern = join '', map { '(.{' . int(2 + rand 3) . '})' } (1 .. 3 + rand 15); 

if (my @captures = $fake_data =~ m{\A $pattern}xms) { 
    print "$pattern\nSubstr:\n"; 

    for (1 .. $#-) { 
     printf "%5d. -> pos%3d -%3d = '%s'\n", $_, $-[$_], $+[$_] - 1, substr($fake_data, $-[$_], $+[$_] - $-[$_]); 
    } 

    print "\nEval:\n"; 

    for (1 .. $#-) { 
     printf "%5d. -> pos%3d -%3d = '%s'\n", $_, $-[$_], $+[$_] - 1, eval "\$$_"; 
    } 

    print "\nList:\n"; 

    my $num = 0; 
    for my $capture (@captures) { 
     $num++; 
     printf "%5d. -> pos%3d -%3d = '%s'\n", $num, $-[$num], $+[$num] - 1, $capture; 
    } 

} else { 
    die "No match"; 
} 

輸出:

(.{3})(.{4})(.{4})(.{4})(.{3})(.{2})(.{2})(.{4})(.{3}) 
Substr: 
    1. -> pos 0 - 2 = 'ABC' 
    2. -> pos 3 - 6 = 'DEFG' 
    3. -> pos 7 - 10 = 'HIJK' 
    4. -> pos 11 - 14 = 'LMNO' 
    5. -> pos 15 - 17 = 'PQR' 
    6. -> pos 18 - 19 = 'ST' 
    7. -> pos 20 - 21 = 'UV' 
    8. -> pos 22 - 25 = 'WXYZ' 
    9. -> pos 26 - 28 = 'ABC' 

Eval: 
    1. -> pos 0 - 2 = 'ABC' 
    2. -> pos 3 - 6 = 'DEFG' 
    3. -> pos 7 - 10 = 'HIJK' 
    4. -> pos 11 - 14 = 'LMNO' 
    5. -> pos 15 - 17 = 'PQR' 
    6. -> pos 18 - 19 = 'ST' 
    7. -> pos 20 - 21 = 'UV' 
    8. -> pos 22 - 25 = 'WXYZ' 
    9. -> pos 26 - 28 = 'ABC' 

List: 
    1. -> pos 0 - 2 = 'ABC' 
    2. -> pos 3 - 6 = 'DEFG' 
    3. -> pos 7 - 10 = 'HIJK' 
    4. -> pos 11 - 14 = 'LMNO' 
    5. -> pos 15 - 17 = 'PQR' 
    6. -> pos 18 - 19 = 'ST' 
    7. -> pos 20 - 21 = 'UV' 
    8. -> pos 22 - 25 = 'WXYZ' 
    9. -> pos 26 - 28 = 'ABC'