使用Perl从文本文件中提取文本

问题描述:

我有一个使用正则表达式从文本文件中提取数据的问题。我有以下格式的文本文件:使用Perl从文本文件中提取文本

REPORTING-OWNER:  

    OWNER DATA: 
     COMPANY CONFORMED NAME:   DOE JOHN 
     CENTRAL INDEX KEY:   99999999999 

    FILING VALUES: 
     FORM TYPE:  4 
     SEC ACT:  1934 Act 
     SEC FILE NUMBER: 811-00248 
     FILM NUMBER:  11530052 

    MAIL ADDRESS: 
     STREET 1:  7 ST PAUL STREET 
     STREET 2:  STE 1140 
     CITY:   BALTIMORE 
     STATE:   MD 
     ZIP:   21202 

ISSUER:  

    COMPANY DATA: 
     COMPANY CONFORMED NAME:   ACME INC 
     CENTRAL INDEX KEY:   0000002230 
     IRS NUMBER:    134912740 
     STATE OF INCORPORATION:   MD 
     FISCAL YEAR END:   1231 

    BUSINESS ADDRESS: 
     STREET 1:  SEVEN ST PAUL ST STE 1140 
     CITY:   BALTIMORE 
     STATE:   MD 
     ZIP:   21202 
     BUSINESS PHONE:  4107525900 

    MAIL ADDRESS: 
     STREET 1:  7 ST PAUL STREET SUITE 1140 
     CITY:   BALTIMORE 
     STATE:   MD 
     ZIP:   21202 

我要救所有者的名称(李四)和标识符(99999999999)和公司的名称(ACME公司)和identfier(0000002230)作为独立变量。但是,如您所见,变量名称(CENTRAL INDEX KEY和COMPANY CONFORMED NAME)对于两条信息都完全相同。

我已经使用下面的代码来提取所有者的信息,但我无法弄清楚如何提取公司的数据。 (注意:我把整个文本文件读入$ data)。

if($data=~m/^\s*CENTRAL\s*INDEX\s*KEY:\s*(\d*)/m){$cik=$1;} 
if($data=~m/^\s*COMPANY\s*CONFORMED\s*NAME:\s*(.*$)/m){$name=$1;} 

任何想法如何我可以为业主和公司提取信息?

谢谢!

有做它快速和肮脏与正则表达式(维护梦魇),或做之间有很大的区别。

碰巧,你给的文件看起来非常像YAML

use YAML; 
my $data = Load(...); 
say $data->{"REPORTING-OWNER"}->{"OWNER DATA"}->{"COMPANY CONFORMED NAME"}; 
say $data->{"ISSUER"}->{"COMPANY DATA"}->{"COMPANY CONFORMED NAME"}; 

打印:

DOE JOHN 
ACME INC 

是不是很酷?所有在几行安全和可维护的代码☺

+0

感谢大家的意见。我试着运行YAML代码,它告诉我,我有不一致的缩进...显然,我需要回去检查并确保我的文件格式正确。 – TaterTots 2013-02-13 23:13:04

my ($ownname, $ownkey, $comname, $comkey) = $data =~ /\bOWNER DATA:\s+COMPANY CONFORMED NAME:\s+([^\n]+)\s*CENTRAL INDEX KEY:\s+(\d+).*\bCOMPANY DATA:\s+COMPANY CONFORMED NAME:\s+([^\n]+)\s*CENTRAL INDEX KEY:\s+(\d+)/ms 

如果你正在读一个UNIX操作系统上此文件,但它是在Windows产生的,那么行尾将由字符对\r\n,而不是仅仅\n表示,在这种情况下,你应该做的

$data =~ tr/\r//d; 

率先摆脱这些\r字符,并阻止他们设法进入$ownname$comname

搜索OWNER DATA:再读一行,拆分:并取最后一个字段。同样对于COMPANY DATA:报头(sortof),对等

+0

为什么不只是从一个正则表达式中提取所有者或公司的所有数据? – 2013-02-13 20:34:37

+1

,因为regexp不是一切的解决方案... – 2013-02-13 21:19:47

而不是试图在字符串中匹配的元素,将它分成线,并正确地解析成数据结构,可以让这种搜索可以容易地制成,如:

$data->{"REPORTING-OWNER"}->{"OWNER DATA"}->{"COMPANY CONFORMED NAME"} 

这应该是相对容易的事情。

+0

但完全没有必要。 – 2013-02-13 20:33:58

+1

正则表达式可以做到这一点。当然。但这并不意味着这是个好主意。 – 2013-02-13 20:48:39

+0

@depesz我和你在一起。在这里使用正则表达式是愚蠢的。 YAML来拯救,并创建你所描述的数据结构! – amon 2013-02-13 20:53:49

同时选择两个信息位,以便您知道您正在获取与所有者或公司相关联的CENTRAL INDEX KEY。

($name, $cik) = $data =~ /COMPANY\s+CONFORMED\s+NAME:\s+(.+)$\s+CENTRAL\s+INDEX\s+KEY:\s+(.*)$/m;