【问题标题】:Perl parsing Text File with regular expressionPerl用正则表达式解析文本文件
【发布时间】:2019-12-07 02:54:19
【问题描述】:

我有一个包含以下随机结构的文件:

USMS 1362224754632|<REQ MSISDN="00966590832186" CONTRACT="580" SUBSCRIPTION="AAA" FORMAT="ascii" TEXT="L2"

USMS 1362224754632|<REQ MSISDN="00966590832186" CONTRACT="580" SUBSCRIPTION="BBB" THRESHOLDID="1" FORMAT="ascii" TEXT="L2"

我正在尝试用 perl 解析它以获得如下值:

1362224754632;00966590832186;580;AAA;L2

下面是代码:

if($Record =~ /USMS (.*?)|<REQ MSISDN="(.*?)" CONTRACT="(.*?)" SUBSCRIPTION="(.*?)" FORMAT="(.*?)" THRESHOLDID="(.*?)" TEXT="(.*?)"/)
{
                              print LOGFILE "$1;$2;$3;$4;$5;$6;$7\n";
}
elsif($Record =~ /USMS (.*?)|<REQ MSISDN="(.*?)" CONTRACT="(.*?)" SUBSCRIPTION="(.*?)" FORMAT="(.*?)" TEXT="(.*?)"/)
{
                              print LOGFILE "$1;$2;$3;$4;$5;$6\n";
}

但我总是:

;;;;;

【问题讨论】:

    标签: perl


    【解决方案1】:

    管道 (|) 是正则表达式中的特殊字符。转义它,例如:\|,它会起作用。

    if($Record =~ /USMS (.*?)\|<REQ MSISDN="(.*?)" CONTRACT="(.*?)" SUBSCRIPTION="(.*?)" FORMAT="(.*?)" THRESHOLDID="(.*?)" TEXT="(.*?)"/)
    

    else 分支也是如此。

    【讨论】:

    • 谢谢,它解决了这个问题。
    【解决方案2】:

    我不会使用单个正则表达式,而是先将数据拆分为单独的部分,然后分别处理它们。

    my($usms_part, $request) = split / \s* \|<REQ \s* /x, $Record;
    
    my($usms_id) = $usms_part =~ /^USMS (\d+)$/;
    
    my %request;
    while( $request =~ /(\w+)="(.*?)"/g ) {
        $request{$1} = $2;
    }
    

    您不必对所有可能的键/值对及其可能的顺序进行硬编码,而是可以在一段代码中对其进行通用解析。

    【讨论】:

    • @Schwern - 我支持你的答案。如果数据文件中的任何键被更改,原始正则表达式将失败 - 这包括:键的顺序、键的拼写和键计数。更好地捕获键/值对的更开放(或通用?),以考虑未来的变化。并存储在索引哈希中,很好的补充。虽然我会使用某种形式的“记录号”作为第一级键:'$request{$rnum}{$1} = $2;'
    • 我也会采用这种方法。
    【解决方案3】:

    改变

    (.*?) 
    

    ([a-zA-Z0-9]*)
    

    【讨论】:

    • 这会给他1362224754632;;;;; 而不仅仅是;;;;;,但不会解决未转义的管道问题。不过,总的来说,这仍然是个好建议。
    【解决方案4】:

    看起来你想要的只是包含在双引号中的字段。

    看起来像这样

    use strict;
    use warnings;
    
    while (<DATA>) {
      my @values = /"([^"]+)"/g;
      print join(';', @values), "\n";
    }
    
    __DATA__
    USMS 1362224754632|<REQ MSISDN="00966590832186" CONTRACT="580" SUBSCRIPTION="AAA" FORMAT="ascii" TEXT="L2"
    USMS 1362224754632|<REQ MSISDN="00966590832186" CONTRACT="580" SUBSCRIPTION="BBB" THRESHOLDID="1" FORMAT="ascii" TEXT="L2"
    

    输出

    00966590832186;580;AAA;ascii;L2
    00966590832186;580;BBB;1;ascii;L2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-13
      • 1970-01-01
      • 2016-04-27
      相关资源
      最近更新 更多