从perl中的一行文本中删除每个第二个单词(或者更好:用空格分隔相邻字符串的字符串)的最佳方法是什么?
来自:
- Mn Gordon Npmsc Snell Npmsc。铁
醇>
我只想检索这个:
- Gordon Snell。
醇>
我试过写一个正则表达式对此进行建模,但到目前为止我都失败了。任何建议将不胜感激!
答案 0 :(得分:4)
这样的事情会做到:
my $i = 0;
my $line = "Mn Gordon Npmsc Snell Npmsc . Fe";
my @words = grep { $i++ % 2 } split /\s+/, $line;
print "@words\n"; # "Gordon Snell ."
基本上,您将该行拆分为由空格分隔的单词列表,然后过滤掉每个第二个元素以将其放入目标数组中。
答案 1 :(得分:3)
不确定这是否是最有效的方法,但为了简单起见,我可能只需在输入字符串上调用split,然后遍历标记,仅打印/保存每秒标记:
my $sentence = "Once sdklf upon asdfk a lkdfj time...";
my $i = 0;
map { print "$_ " unless $i++ % 2; } (split /\s+/, $sentence);
以上代码打印以下内容:
Once upon a time...
答案 2 :(得分:2)
您可以执行s/\s+\S+(\s+|$)/$1/g
之类的操作,但这不是很易读。它可能会更清楚(如果更冗长一点)到空格上split
并显式选择/打印/结果列表中的每个第二个元素。
答案 3 :(得分:1)
s/(\s*\S+\s+)\S+\s*/$1/g
似乎可以让你到达那里,在行的开头和最后一个未删除的单词之后保留空格。目前尚不清楚是否要在删除的单词之前或之后保留空格(或者是否重要)。
foreach $a (
"1. Mn Gordon Npmsc Snell Npmsc . Fe",
"i've tried to write a regular expression modeling this,",
"but i've failed so far. any suggestions appreciated!"
) {
$_=$a;
s/(\s*\S+\s+)\S+\s*/$1/g;
print "$_\n";
}
1. Gordon Snell .
i've to a expression this,
but failed far. suggestions
答案 4 :(得分:1)
如果不考虑空白保存,则以下工作为单行:
$ perl -pale '$_ = "@F[ grep { !($_ % 2) } 0..$#F ]"' input.dat
测试提供的样本:
$ echo "1. Mn Gordon Npmsc Snell Npmsc . Fe" | perl -pale '$_ = "@F[ grep { $_ % 2 } 0..$#F ]"'
1. Gordon Snell .