perl 正则表达式太贪心了

perl regex too greedy

我经历了其他成员提出的类似问题,并应用(或尝试应用)他们询问的解决方案,但他们没有解决我的问题。我的模式匹配和分组太贪心了,不会在第一个管道 (|) 处停止。如果我说得更具体一些,我认为可以,但我想弄清楚如何在管道的第一个实例中停止模式匹配?

这里有几行

09:30:00.063|IN:|8=FIX.4.2|9=206|35=D|34=5159|49=CLIENT|52=20191024-13:30:00.050|56=SERV|57=DEST|1=05033|11=ABZ5702|15=USD|21=1|38=2000|40=2|44=92.48|47=A|54=5|55=RC|60=20191024-13:30:00.050|111=0|114=N|336=X|5700=AP|9281=SOV|10=202
09:37:21.208|IN:|8=FIX.4.2|9=170|35=D|34=5184|49=CLIENT|52=20191024-13:37:21.206|56=SERV|57=ATXB|1=J5129|11=136404|15=USD|21=1|38=100|40=2|44=1.39|47=A|54=2|55=DIW|59=2|60=20191024-13:30:00.206|10=029

我希望我的 perl 脚本 return 上述数据的以下输出:

09:30:00.063|13:30:00.050|ABZ5702
09:37:21.208|13:37:21.206|136404

我尝试了所有这些和其他几个版本,但无法生成上述输出:

    #$msg =~ s/([^|]*).*|52=([^|]*).*|11=([^|]*).*/||/;
    $msg =~ s/(.+)\|??.*|52=([^|]*).*|11=([^|]*).*/||/;
    #$msg =~ s/^([^|]*).??|52=([^|]*).??|11=([^|]*).*/||/;
    #$msg =~ s/^([^\|??]*).*|52=([^\|??]*).*|11=([^\|??]*).*/||/;
    #$msg =~ s/(.*\|??).*|52=(.+\|??).*|11=(.+\|??).*/one |two |three /;
    #$msg =~ s/(.*?|).*|52=(.*?|).*|11=(.*|?).*/||/;
    #$msg =~ /(.*)|??.*|52=(.*)|??.*|11=(.*)|??.*/||/;
    #$msg =~ s/|.*-[0-3][0-9]:/|/;

print "$msg\n";```

我知道给猫剥皮的方法不止一种,但在某些情况下我需要使用模式匹配方法。我怎样才能使用模式匹配在第一个管道 (|) 停止每个组的地方生成预期的输出?有人可以告诉我我做错了什么吗?

试试这个: s/(.*?)\|.*\|52=([^|]*).*\|11=([^|]*).*/ /;

有几个竖线分隔符需要转义。

你需要看看非贪婪匹配https://docstore.mik.ua/orelly/perl/cookbook/ch06_16.htm

第一个匹配组是(.*?)而不是(.*)? 表示我们匹配的越少越好。

一般来说,在perl中解析FIX,只要没有重复组,我建议先在|上拆分,然后创建标签值对的散列。

我会做一些不同的事情 - 将行拆分为数组并处理数组的单个元素。

如果行的格式预先确定并且永远不会改变,则正则表达式可能是一种特定情况下可接受的解决方案。

use strict;
use warnings;

use Data::Dumper;

my $debug = 0;

while( my $line = <DATA> ) {
    my @array = split /\|/, $line;

    print Dumper(\@array) if $debug;

    $array[7]  =~ s/.+?-//;
    $array[11] =~ s/\d+=//;

    printf "%s\n", join '|', @array[0,7,11];

}

__DATA__
09:30:00.063|IN:|8=FIX.4.2|9=206|35=D|34=5159|49=CLIENT|52=20191024-13:30:00.050|56=SERV|57=DEST|1=05033|11=ABZ5702|15=USD|21=1|38=2000|40=2|44=92.48|47=A|54=5|55=RC|60=20191024-13:30:00.050|111=0|114=N|336=X|5700=AP|9281=SOV|10=202
09:37:21.208|IN:|8=FIX.4.2|9=170|35=D|34=5184|49=CLIENT|52=20191024-13:37:21.206|56=SERV|57=ATXB|1=J5129|11=136404|15=USD|21=1|38=100|40=2|44=1.39|47=A|54=2|55=DIW|59=2|60=20191024-13:30:00.206|10=029