Perl RegEx匹配11列文件

时间:2010-08-10 19:56:01

标签: regex perl

我正在尝试编写一个perl正则表达式来匹配包含11列的第5列文件。还有一个不是数据的序言和页脚。关于如何做到这一点的任何好的想法?这是我到目前为止所做的:

if($line =~ m/\A.*\s(\b\w{9}\b)\s+(\b[\d,.]+\b)\s+(\b[\d,.sh]+\b)\s+.*/i) {

这就是表格的样子:


    No. Form 13F File Number    Name

    ____    28-________________ None

    [Repeat as necessary.]

                          
FORM 13F INFORMATION TABLE

                     TITLE OF             VALUE    SHRS OR  SH /PUT/  INVESTMENT   OTHER    VOTING AUTHORITY
   NAME OF INSURER     CLASS   CUSSIP    (X$1000)   PRN AMT  PRNCALL  DISCRETION  MANAGERS    SOLE    SHARED   NONE
Abbott Laboratories com 2824100 4,570   97,705  SH  sole    97,705  0   0
Allstate Corp   com 20002101    12,882  448,398 SH  sole    448,398 0   0
American Express Co com 25816109    11,669  293,909 SH  sole    293,909 0   0
Apollo Group Inc    com 37604105    8,286   195,106 SH  sole    195,106 0   0
Bank of America com 60505104    174 12,100  SH  sole    12,100  0   0
Baxter Internat'l Inc   com 71813109    2,122   52,210  SH  sole    52,210  0   0
Becton Dickinson & Co   com 75887109    8,216   121,506 SH  sole    121,506 0   0
Citigroup Inc   com 172967101   13,514  3,594,141   SH  sole    3,594,141   0   0
Coca-Cola Co.   com 191216100   318 6,345   SH  sole    6,345   0   0
Colgate Palmolive Co    com 194162103   523 6,644   SH  sole    6,644   0   0

4 个答案:

答案 0 :(得分:1)

我认为正则表达式对此有点过分。

我要做的是清理输入并在文件上使用Text::CSV_XS,指定记录分隔符(sep_char)。

答案 1 :(得分:1)

像以太一样,另一种工具适合这项工作。

    @fields = split /\t/, $line;
    if (@fields == 11) {  # less than 11 fields is probably header/footer
        $the_5th_column = $fields[4];
        ...
    }

答案 2 :(得分:1)

如果你这么长时间写一个正则表达式,你至少应该使用x标志来忽略空格,重要的是允许空格和注释:

m/
  whatever
  something else   # actually trying to do this
  blah             # for fringe case X
  /xi

如果你发现很难阅读自己的正则表达式,其他人会发现它是不可能的。

答案 3 :(得分:0)

我的第一个想法是,示例中的示例数据非常严重。很高兴看到它嵌入在一些<pre>...</pre>标签中,因此将保留列。

如果你正在处理柱状数据,你可以使用substr()或unpack()比使用正则表达式更容易。您可以使用正则表达式来解析数据,但是我们大多数人一直在编写Perl编程时也了解到正则表达式并不是第一个抓取很多次的工具。这就是你得到其他评论的原因。正则表达式是一种强大的武器,但它也很容易用脚射击自己。

http://perldoc.perl.org/functions/substr.html

http://perldoc.perl.org/functions/unpack.html

更新

在美国证券交易委员会埃德加网站上发现一点点后,我发现13F文件的格式很好。而且,你应该没有问题找出如何使用substr和/或解包来处理它们。

                                                     FORM 13F INFORMATION TABLE
                                                             VALUE  SHARES/ SH/ PUT/ INVSTMT  OTHER            VOTING AUTHORITY
NAME OF ISSUER                 TITLE OF CLASS   CUSIP     (x$1000)  PRN AMT PRN CALL DSCRETN MANAGERS         SOLE   SHARED     NONE
- ------------------------------ ---------------- --------- -------- -------- --- ---- ------- ------------ -------- -------- --------
3M CO                          COM              88579Y101      478     6051 SH       SOLE                     6051        0        0
ABBOTT LABS                    COM              002824100      402     8596 SH       SOLE                     8596        0        0
AFLAC INC                      COM              001055102      291     6815 SH       SOLE                     6815        0        0
ALCATEL-LUCENT                 SPONSORED ADR    013904305      172    67524 SH       SOLE                    67524        0        0

如果您看到13F文件未格式化,如您的示例所示,那么您无法正确查看,因为某些文件中的列之间存在选项卡。

我查看了68个文件以了解其中的内容,然后编写了一个快速的基于解包的例程并得到了这个:

3M CO, COM, 88579Y101, 478, 6051, SH, , SOLE, , 6051, 0, 0
ABBOTT LABS, COM, 002824100, 402, 8596, SH, , SOLE, , 8596, 0, 0
AFLAC INC, COM, 001055102, 291, 6815, SH, , SOLE, , 6815, 0, 0
ALCATEL-LUCENT, SPONSORED ADR, 013904305, 172, 67524, SH, , SOLE, , 67524, 0, 0

基于其他一些文件,这里有一些关于如何处理它们的想法:

某些文件使用标签来分隔列。这些都很容易解析,你需要正则表达式来拆分列。 0001031972-10-000004.txt似乎就是这样,看起来与你的例子非常相似。

有些文件使用标签来对齐列,将它们分开。您需要弄清楚如何将多个选项卡运行压缩到单个选项卡中,然后可能会拆分选项卡以获取列。

其他人使用空白行垂直分隔行,因此您需要跳过空白行。

其他人允许换行到下一行(就像电子表格会在一个不够宽的列中。要弄清楚如何解决这个问题并不难,但如何做到这一点仍然留作练习你。

有些使用居中的列对齐,导致数据中的前导和尾随空格。 s/^\s+//;s/\s+$//;将成为您的朋友。

我看到的最有趣的一个似乎是正确创建的,然后在第78列进行了单词包装,这让我想到一些白痴将他们的电子表格或报告加载到他们的文字处理器然后保存了它。读取这是摆脱包装回车的两步过程,然后重新处理数据以解析列。作为一项附加任务,他们在分页数据中也有列标题。

您应该能够获得100%的解析文件,但是由于使用了制表符和空行以及嵌入的列标题,您可能希望使用几种不同的解析方法。

啊,处理来自荒野的数据的乐趣。