2

我正在研究填字游戏编译器。

例如,假设有 8 个空白点,“U”在第二个点,“E”在第 4 个点,“E”在第 6 个点。

_U_E_E___

我有一个单词列表,我试图从中获取与此匹配的单词。如果我找到一个带有这种模式的 8 个字母的单词(TUBELESS),太好了!但是,如果我能找到一个仅匹配前 4 个插槽(TUBE)的 4 个字母单词,我也可以使用它。

我可以为每个可能的长度设置一个 RE,并使用 '|' 组合它们 但我正在寻找更优雅的解决方案。帮助?

4

4 回答 4

1

这是一个稍微简洁的正则表达式。我假设您的字典中的单词没有数字,因此匹配字母数字字符不会有问题。如果不是这种情况,只需在表达式中替换\w为。[A-Z]

import re

#REGEX EDIT:
#added so that the expression can't be embedded in another string
# ^ = beginning, $ = end

#to match words that are either 4 or 8 characters long:
#specify a group of 4 letters at the end, then match it 0 or 1 times with "?"
regex = re.compile(r"^\wU\wE(\wE\w{2})?$")

x = 'TUBELESS'
y = 'TUBE'

#both these options return a match object
#meaning they fit the regular expression
regex.match(x)
regex.match(y)
于 2013-10-24T06:00:02.360 回答
1

使用嵌套的可选组:.U.E(?:.(?:E(?:..?)?)?)?$

您可以使用一个简单的递归函数来构建模式:(几乎相同的模式,但即使是最后一个字符也被包装在一个组中)

def nested_pattern(s):
    if s:
        return '(?:' + s[0] + nested_pattern(s[1:]) + ')?'
    else:
        return ''

import re
regex = re.compile(r'.U.E' + nested_pattern(r'.E..') + '$')

for word in ('TUB', 'TUBE', 'TEBU', 'TUBES', 'PURETE', 'TUBELEX', 'TUBELESS', 'SURELY'):
    print word, bool(regex.match(word))

印刷

TUB False
TUBE True
TEBU False
TUBES True
PURETE True
TUBELEX True
TUBELESS True
SURELY False
于 2013-10-24T06:05:22.703 回答
0

具有您想要的匹配项的 4 到 8 个字符的字符串是:

>>> p = re.compile('^[A-Z]U[A-Z]E(?=[A-Z](?=E(?=[A-Z](?=[A-Z]$|$)|$)|$)|$)')
>>> re.match(p, 'TUB')
>>> re.match(p, 'TUBE')
<_sre.SRE_Match object at 0x10fe55ac0>
>>> re.match(p, 'TUBX')
>>> re.match(p, 'TUBEL')
<_sre.SRE_Match object at 0x10fe55b28>
>>> re.match(p, 'TUBELE')
<_sre.SRE_Match object at 0x10fe55ac0>
>>> re.match(p, 'TUBELEX')
<_sre.SRE_Match object at 0x10fe55b28>
>>> re.match(p, 'TUBELES')
<_sre.SRE_Match object at 0x10fe55ac0>
>>> re.match(p, 'TUBELESS')
<_sre.SRE_Match object at 0x10fe55b28>
>>> re.match(p, 'TUBELESSY')
>>> re.match(p, 'TUBELESS7')
>>> re.match(p, 'TUBELEZZ')
<_sre.SRE_Match object at 0x10fe55ac0>
>>> re.match(p, 'TUBELE88')

我不确定这是否“更优雅”,但它是前瞻的有趣例证。也许它会为你产生一些想法?

于 2013-10-24T05:47:17.657 回答
0
text = "_U_E_E___"
def solve(text, word_list):
    for word in word_list:
        matches = 0
        for c1, c2 in zip(text, word):
            if not(c1 == c2 or c1 == '_'):
                break
            matches += 1 
        if matches >= 4:
            return word


print solve(text, ['TXBELESS', 'TUBE'])
print solve(text, ['TXBELESS', 'TUBx', 'TUBELESS', 'TUBEL'])

输出:

TUBE
TUBELESS
于 2013-10-24T05:50:14.240 回答