有没有办法指定一个字母在单词中出现多少次而不指定顺序,即#34;我希望匹配两个或更少的z&1;以及1个或更少的u' s ,但是以任何顺序"?
我在使用python的正则表达式找到与拼字游戏“机架”匹配的单词时遇到问题。这是从命令行参数获得的。机架本质上是一个随机数字(例如python scrabble.py uzz)。
以下代码接近我要实现的内容:
matches = re.findall( '^[' + rack + ']{3,'+ str(len(rack)) + '}$', dictionary, re.IGNORECASE|re.MULTILINE)
[' + rack + ']
为我提供了我的角色范围。
{3,'+ str(len(rack)) + '}
指定给定的字符数为3(所有单词的长度至少为3个字母)。
^
和$
指定我们必须匹配字符串的开头到结尾。
但是,当我提供zuz
时,我会收到以下匹配['ZUZ', 'ZZZ']
。正如您所看到的,ZZZ
不应该匹配,因为我没有提供3个Z.
答案 0 :(得分:0)
像^(?=[^z]*z?[^z]*z?[^z]*$)(?=[^u]*u?[^u]*$)\w+$
这样的东西
如果您正在寻找子串,请用\b
替换锚点。
解释
^ # BOS
(?= [^z]* z? [^z]* z? [^z]* $ ) # Two or less z's
(?= [^u]* u? [^u]* $ ) # One or less u's
\w+ # word chars
$ # EOS
如果您需要不区分大小写的匹配,请添加(?i)
。
请注意,您可以通过编程方式构造正则表达式,以便不仅找到
这封信,但你允许的数字。
模板是
not_letter = '[^' + <letter> + ']*';
letter = <letter> + '?';
times_allowed = '{0,' + <times> + '}';
rx_letter = '(?=' + not_letter + '(?:' + letter + not_letter + ')' + times_allowed;
来自coments,一个有效^(?=[^z]*z[^z]*z?[^z]*$)(?=[^u]*u[^u]*$)[uz]{3}$
解释
^ # BOS
(?= [^z]* z [^z]* z? [^z]* $ ) # 1 but no more than 2 z's
(?= [^u]* u [^u]* $ ) # 1 but no more than 1 u's
[uz]{3} # Only u or z, exactly 3 chars
$ # EOS
请注意,最后一个表格也可以是程序化的。
示例
^ # BOS
(?= # 1 but no more than 4 z's
[^z]* z
(?: [^z]* z? ){3} # Quantifier = 4 - 1
[^z]* $
)
(?= # 1 but no more than 3 u's
[^u]* u
(?: [^u]* u? ){2} # Quantifier = 3 - 1
[^u]* $
)
[uz]{9} # Only u or z, exactly 8 chars
$ # EOS
答案 1 :(得分:0)
您可以通过匹配每个字典单词的字母排序版本找到所有匹配的字典单词。然后匹配就容易多了:然后你对机架上的字母进行排序,并在每个字母后面放 sorted(l[:i]+l[i:]) + [l[i]]
,使它们在正则表达式匹配中可选:
?
我将@Hamish:s answer中的前几个单词加载到https://www.wordgamedictionary.com/sowpods/download/sowpods.txt的字符串中。