2013-03-18 55 views
0

我正嘗試在perl中流式傳輸文件並標記行幷包含令牌。包含掃描令牌的正則表達式令牌的perl流文件

我:

while($line =~ /([\/][\d]*[%].*?[%][\d]*[\/]|[^\s]+|[\s]+)/g) { 
    my $word = $1; 
    #... 
} 

但是,當有令牌沒有空格這是行不通的。

例如,如果我的路線是:

$line = '/15%one (1)(2)%15/ is a /%good (1)%/ +/%number(2)%/.' 

我想拆分行成:

$output = 
[ 
    '/15%one (1)(2)%15/', 
    ' ', 
    'is', 
    ' ', 
    'a', 
    '/%good (1)%/', 
    ' ', 
    '+', 
    '/%number(2)%/', 
    '.' 
] 

什麼是做到這一點的最好方法是什麼?

回答

2

(?:(?!STRING).)*STRING[^CHAR]*CHAR,所以

my @tokens; 
push @tokens, $1 
    while $line =~ m{ 
     \G 
     (\s+ 
     | ([\/])([0-9]*)% 
     (?: (?! %\3\2).)* 
     %\3\2 
     | (?: (?! [\/][0-9]*%)\S)+ 
    ) 
    }sxg; 

但不驗證。如果你想驗證,你可以使用

my @tokens; 
push @tokens, $1 
    while $line =~ m{ 
     \G 
     (\s+ 
     | ([\/])([0-9]*)% 
     (?: (?! %\3\2).)* 
     %\3\2 
     | (?: (?! [\/][0-9]*%)\S)+ 
     | \z (*COMMIT) (*FAIL) 
     | (?{ die "Syntax error" }) 
    ) 
    }sxg; 

下也驗證,但它是一個有點更具可讀性和更容易區分令牌類型:

my @tokens; 
for ($line) { 
    m{\G (\s+) }sxgc 
     && do { push @tokens, $1; redo }; 

    m{\G (([\/])([0-9]*)% (?: (?! %\3\2).)* %\3\2) }sxgc 
     && do { push @tokens, $1; redo }; 

    m{\G ((?: (?! [\/][0-9]*%)\S)+) }sxgc 
     && do { push @tokens, $1; redo }; 

    m{\G \z }sxgc 
     && last; 

    die "Syntax error"; 
} 

pos會得到你的信息關於發生錯誤的位置。