多层次的grep

时间:2012-04-21 15:46:35

标签: regex

我有一系列格式如下的HTML文件:

cinema name
 film 1
  showtime 1
  showtime 2
  ...

 film 2
  showtime 1
  showtime 2
  showtime 3
  ...

电影院的名字只列在顶部一个;然后有一个电影列表(任何数量的电影可以在这里,从1到n),然后是一个放映时间列表(再次,它可能是白天1或更多。

我想使用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完成此操作。可能吗?如果是这样,怎么样?

2 个答案:

答案 0 :(得分:1)

您不必使用单个正则表达式解决所有问题。在这种情况下,我只想知道领先的空白我有哪种线,记住电影和电影的价值,然后在我进入showtime时将它们全部打印在一起。虽然这个解决方案是在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

答案 1 :(得分:0)

单个表达式是不可能的,但您可以在五个表达式中完成:

删除空白行(简化了一些内容):     发现:“\ n \ n”     替换:“\ n”

填写电影:

(在电影之后找到以任意数量的前放映时间为前缀的放映时间。电影被捕获,然后被添加到放映时间的开头。)

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

填写电影院:

(查看以电影放映之后任意数量的放映时间或电影为前缀的放映时间。电影被捕获,然后添加到放映时间的开头。)

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

删除非showtime行:

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

修剪放映时间:

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

所有这些都是未经测试的,并假定使用\n行终止符的类似.NET的正则表达式语法。调整味道。