2013-02-13 109 views
2

我有一個使用正則表達式從文本文件中提取數據的問題。我有以下格式的文本文件:使用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;} 

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

謝謝!

回答

3

有做它快速和骯髒與正則表達式(維護夢魘),或做之間有很大的區別。

碰巧,你給的文件看起來非常像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

0
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

-1

搜索OWNER DATA:再讀一行,拆分:並取最後一個字段。同樣對於COMPANY DATA:報頭(sortof),對等

+0

爲什麼不只是從一個正則表達式中提取所有者或公司的所有數據? – 2013-02-13 20:34:37

+1

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

0

而不是試圖在字符串中匹配的元素,將它分成線,並正確地解析成數據結構,可以讓這種搜索可以容易地製成,如:

$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

0

同時選擇兩個信息位,以便您知道您正在獲取與所有者或公司相關聯的CENTRAL INDEX KEY。

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