2

如何使用 grep 从字典文件中查找出现的单词,这些单词具有给定的一组字母,并且每个字母出现一次且仅出现一次。

EG 如果字母是 abc,那么预期的输出是:

出租车


编辑:

给定一个字典文件(即每行包含一个单词的文件,例如/usr/share/dict/words在 mac os x 操作系统上)和一组(唯一)字符,我想打印出字典文件中包含输入的每个字符的所有单词设置一次且仅一次。例如,如果字符集{a,b,c}随后打印出包含该字符集的每个字符的所有(3 个字母)单词。

我正在寻找一种仅使用 grep 表达式的解决方案。

4

4 回答 4

1

例如,给定一系列字母,abc您可以将每个字母转换为前瞻,如下所示:

^(?=[^a]*a[^a]*)(?=[^b]*b[^b]*)(?=[^c]*c[^c]*)$

您可能需要使用“扩展正则表达式”标志-E来将此正则表达式与grep.


要从字符串创建此正则表达式,您可以使用sed(读者练习)

于 2013-03-05T18:58:34.263 回答
1
grep -E ^[abc]{3}.$ <Dictionary file> | grep -v -e a.*a -e b.*b -e c.*c

即找到与输入匹配的所有三个字母字符串,并通过反向 grep 将这些字符串通过管道删除带有双字母的字符串。

我正在使用“。” 在 {3} 之后,因为我的字典文件是基于 Windows 的,所以有一个额外的回车或换行。所以,这可能没有必要。

于 2013-08-17T20:29:57.497 回答
0

下面是一个 Perl 解决方案。请注意,您需要向字典中添加更多单词,并将输入读入$input变量。一个有效单词数组最终会出现在@results.

#!/usr/bin/env perl

use Data::Dumper;

my $input = "abc";

my @dictionary = qw(aaa aac aad aal aam aap aar aas aat aaw aba abc abd abf abg
  abh abm abn abo abr abs abv abw aca acc ace aci ack acl acp acs act acv ada adb
  adc add adf adh adl adn ado adp adq adr ads adt adw aea aeb aec aed aef aes aev
  afb afc afe aff afg afi afk afl afn afp aft afu afv agb agc agl agm agn ago agp
  ...

  PUT A REAL DICTIONARY HERE!

  ...
  zie zif zig zii zij zik zil zim zin zio zip zir zis zit ziu ziv zlm zlo zlx zma
  zme zmi zmu zna zoa zob zoe zog zoi zol zom zon zoo zor zos zot zou zov zoy zrn
  zsr zub zud zug zui zuk zul zum zun zuo zur zus zut zuz zva zwo zye zzz);

# Generate a lookahead expression for each character in the input word
my $regexp = join("", map { "(?=.*$_)" } split(//, $input));

my @results;
foreach my $word (@dictionary) {

  # If the size of the input doesn't match the dictionary word, skip to the
  # next word.
  if (length($input) != length($word)) {
    next;
  }

  if ($word =~ /$regexp/) {
    push(@results, $word);
  }
}

print Dumper @results;
于 2013-03-04T19:31:30.020 回答
0

我找到的解决方案涉及使用grepfirst 从输入集中提取所有仅包含字母的 n 字母单词 - 尽管有些字母可能出现不止一次,但有些可能不会出现;(我再次假设输入字母是唯一的)。然后它会执行一系列 1 字母greps以确保每个字母至少出现一次。因为单词的长度为 n,这确保了单词包含每个字母一次且仅一次。例如,如果输入字符集是,(a,b,c}那么解决方案是:

grep -E '^[abc]{3}$' /usr/share/dict/words | grep a | grep b | grep c

可以编写一个简单的 bash 脚本,它创建这个grep字符串并针对 word 文件执行它,使用 $1 作为输入字母集。它可能不是生成字符串的最有效方法,但由于我不熟悉,sed或者awk它似乎确实解决了我的问题。我创建的脚本是:

#!/bin/sh
slen=${#1}
g2="'^[$1]{$slen}\$'"
g3=""
ix1=0
while [ $ix1 -lt $slen ]
do
  g3="$g3 | grep ${1:$ix1:1}"
  ix1=$((ix1+1))
done
eval grep -E $g2 /usr/share/dict/words $g3
于 2013-03-08T00:51:46.030 回答