如何从单词列表创建正则表达式?

8 投票
2 回答
2843 浏览
提问于 2025-04-17 16:18

我有一个包含单词的字典(其实我有的是动词变位的嵌套字典,但这不是重点),我想通过组合这些单词来创建一个正则表达式。

{
  'yo': 'hablaba',
  'tú': 'hablabas',
  'él': 'hablaba',
  'nosotros': 'hablábamos',
  'vosotros': 'hablabais',
  'ellos': 'hablaban',
  'vos': 'hablabas',
}

... 这样可以得到:

'habl((aba(s|is|n)?)|ábamos)' # I think that's right

如果我不包括 'hablábamos',那就简单多了——它们都有相同的前缀,我可以得到:

'hablaba(s|is|n)?'

... 但我想要一个通用的形式。这样做可能吗?

2 个回答

3

我觉得你需要换个简单点的方法

>>> x={
...   'yo': 'hablaba',
...   'tú': 'hablabas',
...   'él': 'hablaba',
...   'nosotros': 'hablábamos',
...   'vosotros': 'hablabais',
...   'ellos': 'hablaban',
...   'vos': 'hablabas',
... }
>>> x
{'t\xc3\xba': 'hablabas', 'yo': 'hablaba', 'vosotros': 'hablabais', '\xc3\xa9l': 'hablaba', 'nosotros': 'habl\xc3\xa1bamos', 'ellos': 'hablaban', 'vos': 'hablabas'}
>>> x.values
<built-in method values of dict object at 0x20e6490>
>>> x.values()
['hablabas', 'hablaba', 'hablabais', 'hablaba', 'habl\xc3\xa1bamos', 'hablaban', 'hablabas']
>>> "|".join(x.values())
'hablabas|hablaba|hablabais|hablaba|habl\xc3\xa1bamos|hablaban|hablabas'

如果你只是用一个交替运算符把哈希值连接起来,那应该就能达到你想要的效果

9

是的,我觉得这是可能的。

为了帮助你入门,我会把这个问题分解成几个步骤。

首先,计算出根字符串,也就是找到一个最长的字符串,这个字符串能够匹配所有被拒绝的值的开头:

>>> root = ''
>>> for c in hablar['yo']:
...     if all(v.startswith(root + c) for v in hablar.itervalues()):
...         root += c
...     else:
...        break
... 
>>> root
'habl'

剩下的单词就会形成一个list,里面是所有的结尾部分。

>>> endings = [v[len(root):] for v in hablar.itervalues()]
>>> print endings
['abas', 'aba', 'abais', 'aba', '\xc3\xa1bamos', 'aban', 'abas']

接下来,你可能需要去掉重复的部分:

>>> unique_endings = set(endings)
>>> print unique_endings
set(['abas', 'abais', '\xc3\xa1bamos', 'aban', 'aba'])

然后把这些结尾部分用管道符号连接起来:

>>> conjoined_endings = '|'.join(unique_endings)
>>> print conjoined_endings
abas|abais|ábamos|aban|aba

形成正则表达式其实很简单,只需要把根字符串和连接后的结尾字符串放在括号里组合起来:

>>> final_regex = '{}({})'.format(root, conjoined_endings)
>>> print final_regex
habl(abas|abais|ábamos|aban|aba)

撰写回答