2012-04-21 54 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