【问题标题】:Extracting words from file but each word once从文件中提取单词,但每个单词一次
【发布时间】:2013-06-03 00:59:40
【问题描述】:

我想编写一个 perl 程序来读取文件并提取其中的日期。但是,如果日期超过一次,我将只打印一次。例如:

On 01/10/2011 I went home. On 02/02/2012, I
went to my school. On 02/02/2012, I went
to London.

输出应该是:

01/10/2011
02/02/2012

我可以通过将日期添加到数组中来做到这一点,并在每次读取新日期时控制它。但我要求一种更有效的方法。有没有合乎逻辑的方法来做到这一点?或 perl 中的任何数据结构?

【问题讨论】:

  • 通过sort -u管道输出?
  • 我认为 [this question][1] 应该可以解决您的问题。 [1]:stackoverflow.com/questions/7651/…
  • 我认为没有办法做到这一点,就像我提到的那样

标签: perl


【解决方案1】:

它将逐行扫描以查找\d\d/\d\d/\d{4} 格式的日期,并将它们作为键保存在哈希中。

文件读取完成后,它会打印这些唯一键。

perl -nE '$s{$_}++ for m| (\d\d/\d\d/\d{4}) |xg;}{say for sort keys %s' file

它可以被翻译成更易读的形式(加上一些检查)

use strict;
open my $fh, "<", "file" or die $!;

my %s;
while (my $line = <$fh>) {

  my @dates = $line =~ m| (\d\d/\d\d/\d{4}) |xg;

  for my $date (@dates) {
    $s{$date} += 1;
  }
}

for my $date (sort keys %s) {

  print $date, "\n";
}

【讨论】:

  • 解释上述答案的作用:使用正则表达式搜索文本以查找 XX/XX/XXXX 形式的所有匹配项,并在字典中递增该键(如果没有,则隐式创建它存在)。然后它只是打印出字典中的键。这和你的建议基本一致。
  • 小术语更正:在 Perl 中,此答案中使用的数据类型称为“哈希”,而不是“字典”。
  • +1 表示解释和严肃的语气。我的回答使用“几乎詹姆斯邦德”开关来啜饮,我认为这对 Unicode 不安全?如果List::MoreUtils 的大部分都在List::Utils(即CORE)中,那就太好了
  • 你可以用-0777 slurp任何二进制文件,所以unicode应该不会有任何麻烦
  • 如何过滤而不是日期创建每个单词所有可能的 4 个字母组合的序列。
【解决方案2】:

如果您愿意安装一个模块来执行此操作(我知道这似乎有点矫枉过正)List::MoreUtils 有一个uniq 方法。大家都别看了……现在是周五下午,天气很热,可能是时候啜饮(-0777)啤酒了:

perl -'MList::MoreUtils qw(uniq)' -0777nE '@dates = m|(\d\d/\d\d/\d{4})|xg ; @x = uniq(@dates); say "@x" ' file.txt

对不起 ;-)

【讨论】:

  • hm,这里它会查找 uniq 并在每一行上打印,但它应该在读取完成后执行这些操作
  • 奇怪,我使用的是 5.18。看看不同版本(perlList::MoreUtils)的行为是否不同可能会很有趣 - perlbrew exec 来救援!无论如何,您的解决方案是无模块的,并且使用蝴蝶 }{,所以最好是默认的 ;-) 干杯!
猜你喜欢
  • 2020-06-24
  • 2013-01-21
  • 1970-01-01
  • 1970-01-01
  • 2012-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多