-1

我有一个包含名称的列表。有多个同名。我想抓住这些伪骗子的第一个实例并锚定它们。

示例输入

Josh Smith
Josh Smith0928340938
Josh Smith and friends

hello
hello1223
hello and goodbye.

我想要做的是识别 or 的第一次出现,Josh Smith并在其前面hello放置一个锚点(例如管道)以进行验证。|这些也是通配符,因为列表很大,所以我不能专门寻找第一个匹配的Josh Smith等等。

我想要的输出是这样的:

|Josh Smith
Josh Smith0928340938
Josh Smith and friends

|hello
hello1223
hello and goodbye.

我没有提供任何代码。我对如何解决这个问题有点不知所措,并希望也许有人在使用正则表达式或 Perl 时遇到过类似的情况。

4

2 回答 2

1

实际上,IMO 这是一个相当有趣的问题,因为您可以发挥创造力。由于您不知道如何识别根名称,所以请问您是否需要?我有一种感觉,您不需要完美的解决方案。因此,我会做一些简单的事情:

#!/usr/bin/perl -wn
$N = 4;

if (@prev) {
    $same_start = length $_ >= $N &&
        substr($prev[0], 0, $N) eq substr($_, 0, $N);

    unless ($same_start) {
        print "|", shift @prev if $#prev;
        @prev = grep { print;0 } @prev;
    }
}
push @prev, $_;

}{ print for @prev

编辑:修正错误:<print "|", shift @prev;> to <print "|", shift @prev if $#prev;>

样本输出:

$ perl josh.pl <josh-input.txt
|Josh Smith
Josh Smith0928340938
Josh Smith and friends

|hello
hello1223
hello and goodbye.
于 2013-10-11T18:27:34.287 回答
1

我认为根据我对您的要求的了解,您正在寻找这样的东西:

$prefix = '';
$buffered = '';
$count = 0;
while ($line = <>) {
    $linePrefix = substr($line,0,length($prefix));
    if ($buffered ne '' && $linePrefix eq $prefix) {
        $buffered .= $line; 
        $count++;
    } else {
        if  ($buffered ne '') {
            print "|" if ($count > 1);  
            print $buffered;
        }
        $buffered = $line;
        $prefix = $line;
        chomp $prefix;
        $count = 1;
    }
}
if ($buffered ne '') {
    if ($count > 1) {
        print "|";
    }
    print $buffered;
}
于 2013-10-11T13:44:48.150 回答