2012-08-17 35 views
0

我一直在研究一个代码,它将解析来自Ical源的事件信息。这是我想按关键术语划分的一大块数据。我需要它以有条不紊的方式完成。我尝试索引关键术语,然后让程序打印这些索引之间的内容。然而由于某种原因,它变成了无限循环打印所有的数据。我不知道如何解决它。不要运行我的代码它会让我的计算机冻结。我希望有人能告诉我我的问题是什么。逻辑解析ICAL feed的难点

不要运行此程序

use strict; 
use warnings; 


use LWP::Simple; 
use HTML::TreeBuilder; 
use HTML::FormatText; 

my $URL= get("https://www.events.utoronto.ca/iCal.php?ical=1&campus=0& 
+sponsor%5B%5D=&audience%5B%5D=&category%5B%5D="); 

my $Format=HTML::FormatText->new; 
my $TreeBuilder=HTML::TreeBuilder->new; 
$TreeBuilder->parse($URL); 
my $Parsed=$Format->format($TreeBuilder); 
open(FILE, ">UOTSUMMER.txt"); 
print FILE "$Parsed"; 
close (FILE); 

open (FILE, "UOTSUMMER.txt"); 
my @array=<FILE>; 

my $string ="@array"; 
my $offset = 0;  # Where are we in the string? 


my $numResults = 0; 

while (1) { 
    my $idxSummary = index($string, "SUMMARY", $offset); 
    my $result = ""; 
    my $idxDescription = index ($string, "DESCRIPTION", $offset); 
    my $result2= ""; 
    if ($idxSummary > -1) { 
     $offset = $idxSummary + length("SUMMARY"); 
     my $idxDescription = index($string, "DESCRIPTION", $offset); 
     if ($idxDescription == -1) { 
      print "(Data malformed: missing DESCRIPTION line.)\n"; 
      last; 
     } 
     if ($idxDescription > -1) { 
      $offset = $idxDescription+ length("DESCRIPTION"); 
      my $idxLocation= index($string, "LOCATION", $offset); 
      if ($idxLocation == -1) { 
       print "(Data malformed: missing LOCATION line.)\n"; 
       last; 
      } 

      my $length = $idxDescription - $offset; 
      my $length2= $idxLocation - $offset; 
      $result = substr($string, $offset, $length); 
      $result2= substr ($string, $offset, $length2); 

      $offset = $idxDescription + length("DESCRIPTION"); 
      $result =~ s/^\s+|\s+$//g ; # Strip leading and trailing white space, including newlines. 
      $result2 =~ s/^\s+|\s+$//g ; 

      $numResults++; 
     } else { 
      print "(All done. $numResults result(s) found.)\n"; 
      last; 
     } 

     open (FILE2, "UOT123.txt") 
     print FILE2 "TITLE: <$result>\n DESCRIPTION: <$result2>\n"; 

你可能将不胜​​感激任何指导!谢谢!

+5

PerlMonks上的Crosspost:http://www.perlmonks.org/?node_id=988015(提及这一点很有礼貌,因此人们不会努力解决可能在其他地方解决的问题,协作努力可能基于全面讨论,而不仅仅是部分讨论。) – DavidO 2012-08-17 16:40:18

+1

请包括您正在使用的实际代码(此代码缺少一些'}')并且一致地缩进它。 – mob 2012-08-17 16:51:36

+0

你是否搜索了“Perl ical”?第一次打击是关于如何解析iCal的文章,第二次和第三次是似乎处理您的问题的CPAN模块。 – 2012-08-17 20:54:06

回答

0

我的灵感来自你的警告,我必须运行它。我甚至安装了所需的模块。你的电脑可能正在陷入无尽的循环,而不是真正的崩溃。

看着你的代码,问题几乎可以肯定你的索引。就目前而言,你的循环逻辑是一团糟。你最好的选择是重新思考你是如何做到这一点的。而不是使用所有这些逻辑,请尝试使循环依赖于通过文件。那样的话,制造一个无限循环将会更加困难。另外,正则表达式将使这个工作更简单。这可能不会做的正是你想要的,但它是一个开始:

while ($string =~ m/SUMMARY(.+?)DESCRIPTION(.+?)(?=SUMMARY|$)/gcs) 
{ 
    print "summary is: \n\n $1 \n\n description is: \n\n $2 \n\n"; 
} 

一些其他的快速点:

  • 写入一个文件,然后打开它,并再次进行读取内容回一开始没有太大意义。你已经有了你想要的$ Parsed。
  • 如果你只是想自己打印一个变量,不要把它放在引号中。这增加了很多开销。
0

也许下面将协助您解析任务:

use Modern::Perl; 
use LWP::Simple qw/get/; 
use HTML::Entities; 

my $html = get 'https://www.events.utoronto.ca/iCal.php?ical=1&campus=0&+sponsor%5B%5D=&audience%5B%5D=&category%5B%5D='; 

while ($html =~ /(Summary:\s*[^\n]+)\s*(Description:\s*[^\n]+)/gi) { 
    say decode_entities($1) . "\n" . decode_entities($2); 
} 

样本输出:

SUMMARY:Learning Disabilities Parent Support Group 
DESCRIPTION: Dates: Thursdays: May 24, June 21, and July 19 

SUMMARY:"Reading to Write" 
DESCRIPTION: Leora Freedman, Coordinator, English Language Learning Program, Faculty of Arts & Science 

SUMMARY:The Irish Home Rule Bill of 1912: A Centennial Symposium 
DESCRIPTION: One-day symposium presented by the Celtic Studies Program, St. Michael's College 

如果HTML实体的文本中都OK,你可以使用HTML::Entities和省略decode_entities($1)表示法,否则您可能会得到如下结果:

DESCRIPTION: Leora Freedman, Coordinator, English Language Learning Program, Faculty of Arts &amp; Science 

希望这有助于!