2012-04-21 61 views
1

我有一系列的被格式化這樣的HTML文件:多的grep

cinema name 
film 1 
    showtime 1 
    showtime 2 
    ... 

film 2 
    showtime 1 
    showtime 2 
    showtime 3 
    ... 

電影院的名字只有一個,列在首位;那麼就有一個電影列表(任何數量的電影可以在這裏,從1到n),然後是一個放映時間列表(同樣,它可以是一天或更多天)

我想提取此信息用grep和輸出是這樣的:

cinema name - film 1 - showtime 1 
cinema name - film 1 - showtime 2 
cinema name - film 2 - showtime 1 
cineme name - film 2 - showtime 2 
cinema name - film 2 - showtime 3 
etc. 
然而

,我不知道是否/如何我可以使用grep做到這一點是有可能如果是這樣,怎麼

回答

0

一個表達式ISN。?不可能,但你可以做到五個:

刪除空白行(簡化了一些stu FF): 查找 「\ n \ n」 個 改爲: 「\ n」

向下填充膜:

(查找由薄膜之後的任何數量的前面場次的前綴一個欣欣。該膜被捕獲,然後加入到所述傳送數據的開頭)

Find: "(?<=\n ([^ \n].+)(\n .*)*)\n " 
Replace: "\n $1 - " 

向下填充電影院:。

(查找由任何數量的一個電影之後先前放映時間或膜的前綴一個放映時間的電影院被捕獲,然後加入到所述傳送數據的開頭)

Find: "(?<=(?:^|\n)([^ \n].+)(\n {1,2}.*)*)\n " 
Replace: "\n $1 - " 

除去非顯示時間線:

Find: "(?<=^|\n)(?! ).*\n" 
Replace: "" 

修剪場次:

Find: "\n " 
Replace: "\n" 

所有這一切都沒有經過測試,並假設類似.NET的正則表達式的語法與\n行終止。調整味道。

1

你不必用一個正則表達式解決所有問題。在這種情況下,我只想弄清楚我的領先空白處是哪一行,記住電影和電影的價值,然後在我進入娛樂時間時將它們一起打印出來。雖然這種解決方案是在Perl中,你可以做任何語言同樣的事情你選擇:

#!perl 
use v5.10; 

my($cinema, $film); 
while(<DATA>) { 
    chomp; 
    if(/\A\S/)   { $cinema = $_ } 
    elsif(/\A\s(\S.*)/) { $film = $1 } 
    elsif(/\A\s\s(\S.*)/) { say "$cinema - $film - $1" } 
    } 


__END__ 
Regal 9 
Jaws 
    15:00 
    19:00 
    21:00 

Star Wars 
    16:00 
    17:00 
    18:00 

AMC 18 
E.T. 
    12:00 
    14:00 

Black Sheep 
    22:00 
    01:00 
    03:00 

這有一個醜陋的Perl一行程序版本:

perl -lne '(/\A\S/ and $c=$_) || (/\A\s(\S.*)/ and $f=$1) || (/\A\s\s(\S.*)/ and print"$c - $f - $1")' movies.txt