2015-04-02 23 views
-1

我有一个大的多行文件来解析,我已经在Perl中陷入了一个单一的字符串。所以它最终是这样的:如何在perl regex中捕获一个字符串的多个“伙伴”?

my $string = "foo1 randomtext bar1 randomtext bar2 randomtext bar3/foo2 randomtext bar4 randomtext bar5 randomtext bar6 bar7/foo3 randomtext bar8 randomtext bar9/"; 

它由一组记录的,每一个都带有一个头条目(foo+number)并且每个由符号分开;在这种情况下为"/"

我试图捕获每个条目(条形码+数字)中的标题信息(foo)和一些文字。在每种情况下,我想要捕获与“bar”的每个实例配对的标题信息,以维护每个条目中特定的foo和bar关系。

我所要的输出是这样的:

foo1_bar1 

foo1_bar2 

foo1_bar3 

foo2_bar4 

foo2_bar5 

foo2_bar6 

foo2_bar7 

foo3_bar8 

foo3_bar9 

我已经后. +,使之最小而不是最大尝试了各种正则表达式的,用的?组合,包括后配套\/记录分隔符(酒吧\ d)(这使得它仅查找记录的最后一个栏,而不是第一),

while ($string =~ m/(foo\d).+?(bar\d)+/g) 
{ 
    print "$1_$2\n"; 
} 

返回

foo1_bar1 

foo2_bar4 

foo3_bar8 

所以只是每个foo的第一个酒吧。 (bar\d)之后基本上+不会使这是一个多重匹配,这就是我的问题。

有什么想法?

+0

请显示数据的原始结构slupring – beasy 2015-04-02 20:20:55

+0

foo1 hfgvkjsdhfjghnsdlkjfg \ n lkhdlkgalkdngf之前\ n; ljfdlkhgnlkdfn \ n BAR1 kjbfdgkjbadkjgbkajdfg \ n kjbfdjgjadfg \ n ljbdfjglnadfg BAR2,jbdfjbadfjbd \ n \ n \ n \ n \ n lhafdgklnaldfglkafd BAR3 lkandfglkhnadfgn \ n \ n ladfglhaf \ n lknadfga/foo2 lahfeglkhaflgk等等等等等等等等(你可以得到图片 - 无法在评论框中输入'actual'回车...) – vienneseFinger 2015-04-02 20:23:26

+0

作为评论,全球比赛像你想要的那样工作并且忽略了什么返回所有foos与尾部酒吧将给foo1_bar1,foo1_bar2,foo1_bar3,foo1_bar4,foo1_bar5 ...因为中间foos会被同样忽略,仍然没有给你期望的结果。 – Oesor 2015-04-02 20:31:01

回答

1

我的做法是在“/”分裂,得到“福”,然后使用一个简单的正则表达式来赶酒吧的:

use strict; 
use warnings; 

my $string = "foo1 randomtext bar1 randomtext bar2 randomtext bar3/foo2 randomtext bar4 randomtext bar5 randomtext bar6 bar7/foo3 randomtext bar8 randomtext bar9/"; 

foreach my $chunk (split(/\//,$string)) { 
    (my $foo = $chunk) =~ s|.*(foo\d).*|$1|; 
    while($chunk =~ m|(bar\d)|g) { 
     print $foo . "_$1\n"; 
    } 
} 
+0

谢谢@leu将我的伪代码放入代码中:) – 2015-04-02 21:29:09

+0

这看起来像一个很好的答案 - 我会试试看,非常感谢。 – vienneseFinger 2015-04-02 22:08:44

+0

然而,你能告诉我这条线是干什么的吗?(my $ foo = $ chunk)=〜s |。*(foo \ d)。* | $ 1 |;?谢谢! – vienneseFinger 2015-04-02 22:40:46

0

无需将文件加载到一个巨大的变种。
你可以避免复杂的正则表达式。

 开始读取文件中的行由行信息$线
     如果$线==^* foo的接盘foovar = $行
     其他
     如果$ line ==^bar * then echo $ foovar_ $ line
 

+0

啊。谢谢,@ Dr._Tyrell。但在真实文件中,randomtext'填充符'跨越1行。所以我使用/ msg修饰符后,我的正则表达式为sl file文件。我可以将这些单独的组件匹配起来(所以我知道它正确地适用于字符串)。 – vienneseFinger 2015-04-02 20:16:02

+2

我只是想到了一些事情......将文件(在他/“)分割成单独的记录和每个记录上的工作(并且全局匹配所有的foo,然后是所有的条目)会更容易。但它可能会起作用... – vienneseFinger 2015-04-02 20:17:34

+0

如果你能够从一大堆垃圾中拼凑出$ string,那么你可能只需要改变你的数据管理脚本就可以坐在每个FOO上,直到下一个FOO出现。
只要作为“foo ??”和“bar ??”的行是独立的,那么'randomtext'的大小并不重要。 – 2015-04-02 21:24:51

2

您可以将字符串过滤为您正在使用的元素兴趣,维持秩序,比遍历数组建立你对:

use strict; 
use warnings; 
use Data::Printer; 

my $string = "foo1 randomtext bar1 randomtext bar2 randomtext bar3/foo2 randomtext bar4 randomtext bar5 randomtext bar6 bar7/foo3 randomtext bar8 randomtext bar9/"; 
my @elements; 

while ($string =~ /((bar|foo)\d)/g) { 
    push @elements, $1; 
} 

my @pairs; 
my $currfoo; 
for my $element (@elements) { 
    if ($element =~ /foo/) { 
     $currfoo = $element; 
    } 
    else { 
     push @pairs, join '_', $currfoo, $element; 
    } 
} 

p(@pairs); 

输出:

[ 
    [0] "foo1_bar1", 
    [1] "foo1_bar2", 
    [2] "foo1_bar3", 
    [3] "foo2_bar4", 
    [4] "foo2_bar5", 
    [5] "foo2_bar6", 
    [6] "foo2_bar7", 
    [7] "foo3_bar8", 
    [8] "foo3_bar9" 
] 
0

让我们记号化和迭代:

#!/usr/bin/env perl 

use feature 'say'; 
use strict; 
use warnings; 

my $string = "foo1 randomtext bar1 randomtext bar2 randomtext bar3/foo2 randomtext bar4 randomtext bar5 randomtext bar6 bar7/foo3 randomtext bar8 randomtext bar9/"; 

my @foo; 
my $tokenizer = make_tokenizer($string); 

while (defined(my $token = $tokenizer->())) { 
    if ($token =~ /\Afoo([0-9])\z/) { 
     push @foo, [$1 => []]; 
    } 
    elsif ($token =~ /\Abar([0-9])\z/) { 
     push @{ $foo[-1][1] }, $1; 
    } 
} 

for my $x (@foo) { 
    my $foo = $x->[0]; 
    for my $bar (@{ $x->[1] }) { 
     say "foo${foo}_bar$bar"; 
    } 
} 

sub make_tokenizer { 
    my $string = shift; 
    sub { 
     return unless length $string; 
     my $token; 
     ($token, $string) = split qr{[ /]}, $string, 2; 
     $token; 
    }; 
} 
相关问题