【问题标题】:Using Perl to extract text from a text file使用 Perl 从文本文件中提取文本
【发布时间】:2013-02-13 20:23:14
【问题描述】:

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

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

我想将所有者的姓名 (John Doe) 和标识符 (99999999999) 以及公司的名称 (ACME Inc) 和标识符 (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;}

知道如何为所有者和公司提取信息吗?

谢谢!

【问题讨论】:

    标签: regex perl text extract


    【解决方案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
    

    这不是很酷吗?只需几行安全且可维护的代码 ☺

    【讨论】:

    • 感谢大家的cmets。我尝试运行 YAML 代码,它告诉我缩进不一致......所以显然我需要返回并检查并确保我的文件格式正确。
    【解决方案2】:
    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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

        与其尝试匹配字符串中的元素,不如将其拆分为行,并正确解析为数据结构,以便轻松进行此类搜索,例如:

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

        这应该相对容易做到。

        【讨论】:

        • 但完全没有必要。
        • 正则表达式可以做到。当然。但这并不意味着这是个好主意。
        • @depesz 我支持你。在这里使用正则表达式是愚蠢的。 YAML 来拯救,并创建您所描述的数据结构!
        • 糟糕。添加了我的代码,后来意识到这与@amon 在他的回答中所做的完全一样:)
        【解决方案5】:

        搜索OWNER DATA: 多读一行,拆分: 并取最后一个字段。 COMPANY DATA: 标头(排序)也一样,依此类推

        【讨论】:

        • 为什么不用一个正则表达式从 $data 中提取所有者或公司的所有内容?
        猜你喜欢
        • 2017-06-16
        • 1970-01-01
        • 1970-01-01
        • 2014-06-09
        • 1970-01-01
        • 2010-11-11
        • 1970-01-01
        • 2021-09-23
        • 1970-01-01
        相关资源
        最近更新 更多