2009-12-22 31 views
2

有沒有一些技巧可以與<>進行多行正則表達式匹配,並循環遍歷它們?這個例子的結果不匹配時上的文件與\n作爲新行分隔符運行:如何對Perl鑽石運算符返回的數據進行多行匹配

while (<> =~ m/\n./) { 
    print($.); 
} 

我需要知道while循環內的比賽開始的行,如示例。

的目標是找到具有少於75個字符,這是隨後開始用空間中的線(分裂排長隊的vCard方式)的所有行:

while (<> =~ m/(^|\n).{0,74}\n /) 

回答

5

你記得通過把多行模式手柄將$/設置爲空字符串還是未定義的值?

下面的程序你想要做什麼:

#! /usr/bin/perl 

use warnings; 
use strict; 

$/ = ""; 

*ARGV = *DATA; 

while (<>) { 
    while (/^(.{0,75}\n(^[ \t].{1,75}\n)*)/mg) { 
    my $vcard = $1; 

    $vcard =~ s/\r?\n[ \t]//g; 

    print $vcard; 
    } 
} 

__DATA__ 
DESCRIPTION:This is a long description that exists on a long line. 
DESCRIPTION:This is a long description 
    that exists on a long line. 
DESCRIPTION:This is a long descrip 
tion that exists o 
n a long line. 

輸出:

 
$ ./try 
DESCRIPTION:This is a long description that exists on a long line. 
DESCRIPTION:This is a long description that exists on a long line. 
DESCRIPTION:This is a long description that exists on a long line. 
6

你在特林在那個正則表達式中做?看起來您正在嘗試查找換行符後面至少有一個字符的任何情況,然後會導致您輸出符合該條件的行號($.)。

如果你不介意我的問題,這裏有什麼更大的目的?

在任何情況下,請參見本文的多匹配的明確論述:在移動後編輯,以SORegexp Power

:如果你真正想要的是少於75個字符並找到線下一行以空格開頭,我不會使用一個正則表達式。這個描述指出了一個更容易和更清晰的(我認爲)解決方案:(1)過濾掉所有少於75個字符的行(length函數對此很有用)。對於剩下的線,(2)檢查下一行是否以空格開始。這給你明確的邏輯和一個簡單的正則表達式來編寫。

迴應關於獲取「下一行」的問題。反過來想想:你想檢查每個下一個行,但只有當前面的行小於75個字符。那麼這個怎麼樣:

my $prev = <>; # Initialize $prev with the first line 

while (<>) { 
    # Add 1 to 75 for newline or chomp it perhaps? 
    if (length $prev < 76) { 
     print "$.: $_" if $_ =~ m/^\s/; 
    } 
    $prev = $_; 
} 

(請注意,我不知道vCard格式的任何或所有\s比字面上更廣所以你可能需要調整代碼以更好地適應你的問題「一個單一的空間。」 )

+0

感謝您的鏈接;不幸的是沒有提到我可以找到的文件句柄。也許這種匹配的方向是錯誤的,但我希望能夠使用'$ .'而不是跟蹤行數和/或跟蹤上一行。 – l0b0

+0

聽起來不錯,但是如何在不從<>中移除下一行? – l0b0

+0

@ l0b0:我認爲你在混合在一起。文章解釋了使用正則表達式進行多行匹配。這就是你最初問的問題。文件句柄與這個問題*本身*無關。請參閱上文以獲取您評論的其他部分。 – Telemachus

3

你有一個任意文本與vCards混合的文件嗎?

如果你所擁有的只是一堆vCards文件,而你想解析它們,那麼有些vCard parsing modules on CPAN

例如參見Text::vCard,特別是Text::vCard::Addressbook

關於,

while (<> =~ m/\n./) { 
    print($.); 
} 

這的確不是因爲一個簡單的事實,即讀取輸入行由行意味着不能有換行後任何事情$_匹配任何東西。

如果再也不會有比單續行更下面每一行少於76個字符,下面可能符合要求:

#!/usr/bin/perl 

use strict; use warnings; 

for 
( 
    my $this = <>, my $next = <>; 
    defined ($next = <>); 
    close ARGV if eof 
) 
{ 
    printf "%s : %d\n", $ARGV, $. - 1 if 76 > length $this and $next =~ /^ /; 
}