3

我收到一个关于解析向量有这样的字符串的问题:

"chr1-247751935-G-.:M92R,chr1-247752366-G-.:R236G,"
"chr1-247951785-G-.:G98K,"
"chr13-86597895-S-78:M34*,chr13-56891235-S-8:G87K,chr13-235689125-S-7:M389L,"

我想得到:

"M92R R236G"
"G98K"
"M34* G87K M389L"

当我使用

while ($info1=~s/^(.*)\:(([A-Z\*]){1}([\d]+)([A-Z\*]){1})\,//) 
{
    $pos=$2; 
}

结果 $pos 只给我每一行的最后一个,即:

"R236G"
"G98K"
"M389L"

我应该如何更正脚本?

4

3 回答 3

2

使用单线:

$ perl -ne 'print q/"/ . join(" ", m/:([^,]+),/g) . qq/"\n/' file
"M92R R236G"
"G98K" 
"M34* G87K M389L"

在脚本中:

$ perl -MO=Deparse -ne 'print "\042" . join(" ", m/:([^,]+),/g) . "\042\n"' file

脚本 :

LINE: while (defined($_ = <ARGV>)) {
    print '"' . join(' ', /:([^,]+),/g) . qq["\n];
}
于 2013-10-24T20:33:36.997 回答
2

您的代码不起作用的原因是您在正则表达式的开头有一个贪婪。 ^(.*)只要其余的模式匹配,这将尽可能多地占用目标字符串,因此您只会找到子字符串的最后一次出现。您可以通过将其更改为非贪婪模式来修复它^(.*?)

关于正则表达式的其他一些说明:

  • 不需要转义:or ,,或者*当它在字符类中时[...]

  • 永远不需要量词{1},因为这是没有量词的模式的效果

  • 无需放入\d字符类[\d],因为它本身就可以正常工作

  • 除非您需要在匹配成功时访问与该子模式匹配的任何子字符串,否则无需将子模式括在括号中。所以,例如^.*没有括号就可以了

您的代码修改与您的代码相同,但更简洁

while ($info1 =~ s/^.*?:([A-Z*]\d+[A-Z*]),// ) {
  my $pos = $1;
  ...
}

但最好的解决方案是使用全局匹配来查找字符串中所有出现的模式,并且不需要在此过程中修改字符串。

该程序按照您的描述进行。它只查找每条记录中冒号后面的所有字母数字或星号字符串。

use strict;
use warnings;

while (<DATA>) {
  my @fields = /:([A-Z0-9*]+)/g;
  print "@fields\n";
}

__DATA__
"chr1-247751935-G-.:M92R,chr1-247752366-G-.:R236G,"
"chr1-247951785-G-.:G98K,"
"chr13-86597895-S-78:M34*,chr13-56891235-S-8:G87K,chr13-235689125-S-7:M389L,"

输出

M92R R236G
G98K
M34* G87K M389L
于 2013-10-24T20:41:31.270 回答
0

您可以将冒号和一些字母数字字符用作正则表达式,使用数组保存它们并在循环结束时打印。这里有一个例子:

#!/usr/bin/env perl;

use strict;
use warnings;

my (@data);

while ( <DATA> ) { 
    while ( m/:([[:alnum:]*]+)/g ) { 
        push @data, $1; 
    }   
    printf qq|"%s"\n|, join q| |, @data;
    undef @data;
}

__DATA__
"chr1-247751935-G-.:M92R,chr1-247752366-G-.:R236G,"
"chr1-247951785-G-.:G98K,"
"chr13-86597895-S-78:M34*,chr13-56891235-S-8:G87K,chr13-235689125-S-7:M389L,"

像这样运行它:

perl script.pl

这会产生:

"M92R R236G"
"G98K"
"M34* G87K M389L"
于 2013-10-24T20:40:27.780 回答