正则表达式只有一个字母不相同的单词

时间:2015-10-09 13:26:39

标签: regex

我想创建一系列益智游戏,您可以在其中更改单词中的一个字母以创建新单词,目的是达到给定的目标单词。例如,要将“this”更改为“that”:

this
thin
than
that

我想要做的是创建一个正则表达式,它将扫描一个单词列表,并选择匹配当前单词的所有单词除了一个字母。例如,如果我的起始单词是“苍白”,而我的单词列表是......

pale
male
sale
tale
pile
pole
pace
page
pane
pave
palm

peal
leap
play
help
pack

...我希望选择“peal”到“pack”的所有单词。这意味着我可以从列表中删除它们,只留下可能是下一个匹配的单词。 (“苍白”本身未被选中是可以的。)

我可以部分地这样做:

  • ^.(?!ale).{3}\n选择的字词不像“* ale”
  • ^.(?<!p).{3}\n|^.{2}(?!le).{2}\n选择的字词不像“p * le”
  • ^.{2}(?<!pa).{2}\n|^.{3}(?!e).\n选择的字词不像“pa * e”
  • ^.{3}(?<!pal).\n选择的字词不像“pal *”。

然而,当我把它们放在一起时......

^.(?!ale).{3}\n|^.(?<!p).{3}\n|^.{2}(?!le).{2}\n|^.{2}(?<!pa).{2}\n|^.{3}(?!e).\n|^.{3}(?<!pal).\n

......除了“苍白”之外的所有东西都匹配。

我需要一些方法在不同的正则表达式之间创建AND关系,或者(更可能)一种完全不同的方法。

4 个答案:

答案 0 :(得分:3)

您可以使用允许模糊匹配的Python regex模块:

>>> import regex
>>> regex.findall(r'(?:pale){s<=1}', "male sale tale pile pole pace page pane pave palm peal leap play help pack")
['male', 'sale', 'tale', 'pile', 'pole', 'pace', 'page', 'pane', 'pave', 'palm']

在这种情况下,您希望替换0或1是匹配。

或者考虑支持类似语法的TRE library和命令行agrep

假设:

$ echo $s 
male sale tale pile pole pace page pane pave palm peal leap play help pack

您可以过滤到单个替换的列表:

$ echo $s | tr ' ' '\n' | agrep '(?:pale){ 1s <2 }'
male
sale
tale
pile
pole
pace
page
pane
pave
palm

答案 1 :(得分:2)

这是一个使用酷python技巧而且没有正则表达式的解决方案:

def almost_matches(word1, word2):
    return sum(map(str.__eq__, word1, word2)) == 3

for word in "male sale tale pile pole pace page pane pave palm peal leap play help pack".split():
    print almost_matches("pale", word)

答案 2 :(得分:2)

完全不同的方法:Levenshtein distance

  

......两个单词之间的Levenshtein距离是将一个单词改为另一个单词所需的最小单字符编辑数(即插入,删除或替换)。

PHP example

int readSize = sharedPreferences.getInt("list_size", 0);
for(int i = 0; i < readSize; i++) {
    myList.add(sharedPreferences.getString("item_" + 1, null);
}

答案 3 :(得分:0)

这假定第一行上的单词是关键字。只是一个强力平行的字母匹配和计数完成工作:

awk 'BEGIN{FS=""}
     NR==1{n=NF;for(i=1;i<=n;++i)c[i]=$i}
     NR>1{j=0;for(i=1;i<=n;++i)j+=c[i]==$i;if(j<n-1)print}'

我认为正则表达式通用解决方案需要是一个2步器 - 在第一步生成正则表达式(从关键字开始),在第二步中对文件运行正则表达式。

顺便说一下,做&#34;和&#34;的方式正则表达式是串向前瞻(并且前瞻者不需要像我想象的那样复杂):

^(?!.ale)(?!p.le)(?!pa.e)(?!pal.)