我得到一个关于解析向量的问题有这样的字符串:
"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"
我该如何更正脚本?
答案 0 :(得分:1)
使用单行:
$ 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];
}
答案 1 :(得分:1)
您的代码无效的原因是您在正则表达式的开头有一个贪心 ^(.*)
。只要模式的其余部分匹配,这将占用尽可能多的目标字符串,因此您将只找到子字符串的 last 次出现。您可以通过将其更改为非贪婪模式^(.*?)
来修复它。
关于你的正则表达式的一些其他注释:
当它位于字符类:
,
或*
或[...]
永远不需要量词{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
答案 2 :(得分:0)
你可以使用冒号作为冒号和一些alpanumerics字符,使用数组来保存它们并在循环结束时打印。这里有一个例子:
#!/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"