搜索 /usr/dict/words 以查找具有某些属性的单词

搜索 /usr/dict/words 以查找具有某些属性的单词

我想编写一个脚本来搜索 /usr/dict/words 以查找满足我指定的某些条件的所有单词。例如,查找所有回文单词(如“racecar”、“madam”等)或查找所有前半部分和后半部分颠倒的单词也形成一个单词(如“german”和“manger”)。脚本的框架将是一个简单的循环,用于读取字典中的每个单词,我可以根据我想要查找的内容,通过替换表达式或类似的内容来更改标准。

我想我需要以某种方式涉及正则表达式(或者找到一种方法来查看每个单词中的单个字符)。我还需要一种方法来将当前单词中的字符与字典中的其他单词进行比较(例如上面的第二个示例)。

执行此任务的最佳工具是什么?

答案1

以下perl脚本从命令行上列出的标准输入和/或文件名读取单词列表,并打印出它找到的所有回文和可逆单词。它会忽略长度小于 3 个字符的单词(主要是因为我的/usr/share/dict/words文件中有很多此类垃圾,例如“A”和“Aa”)

这是用极其简单的 Perl 编写的,旨在尽可能易于理解和修改,而不使用任何“聪明”的 Perl 技巧。

#! /usr/bin/perl

use strict;

my %dict = ();

print "Palindromes\n";
print "-----------\n";

while(<>) {
   chomp;
   next if (length($_) < 3);

   $dict{$_} = 1;
   print "$_\n" if ($_ eq reverse($_));
}


print "\n\nReversibles\n";
print "-----------\n";
foreach my $key (keys %dict) {

    my $len = length($key);
    my $firsthalf = '';
    my $secondhalf = '';

    if (($len / 2) == int($len/2)) {
        # even length words
        $firsthalf = substr($key,0,int($len/2));
        $secondhalf = substr($key,int($len/2));
    } else {
        # odd length words
        $firsthalf = substr($key,0,int($len/2)+1);
        $secondhalf = substr($key,int($len/2)+1);
    };

    my $rev = $secondhalf . $firsthalf;

    next unless (exists $dict{$rev});

    # don't print if reversed word is a palindrome
    next if ($rev eq $key);

    print  "$key => $rev\n";
}

产生如下输出:

$ ./find-P-and-R.pl /usr/share/dict/words
Palindromes
-----------
MGM
aba
abba
aga
aha
aia
aka
...
...
...


Reversibles
-----------
mode => demo
reenter => terreen
juba => baju
oon => noo
lave => vela
lassi => silas
updo => doup
air => rai
...
...
...

答案2

如果您只需要过滤正则表达式,请使用grep.但您想要的不仅仅是正则表达式。您可以使用任何您熟悉的编程语言。 Awk 存在于所有 POSIX 系统上,并且可以轻松地逐行处理文件,但其编程功能并不是一流的。 Perl 可以轻松地进行逐行处理,并且具有更好的字符串处理以及许多可用的库。 Python 很容易学习,并且有一组非常好的可用库。还有很多其他的可能性。

要检查回文,在 *BSD 和 Linux 上,您可以使用rev管道中的实用程序。它反转文件的每一行。查找回文:

rev /usr/dict/words | paste /usr/dict/words - | sed -n 's/^\(.*\)\t\1$/\1/p'
perl -l -ne 'print if reverse($_) eq $_' /usr/dict/words

查找可逆单词:

rev /usr/dict/words | grep -Fxf /usr/dict/words
perl -l -ne '$dict{$_} = 1; END {foreach (keys %dict) {print if $dict{reverse($_)}}}'

答案3

使用 sed 命令的反向引用和子表达式可以做很多事情。下面是两个例子:

示例1:在字典中查找中间带有o的3个字母的回文词

  $ sed -E -n '/^(.)o\1$/p' /usr/share/dict/words
  bob
  mom
  non
  pop
  sos
  tot
  wow

示例 2:查找 6 个字母的回文单词

  $ sed -E -n '/^(.)(.)(.)\3\2\1$/p' /usr/share/dict/words
  redder

相关内容