【问题标题】:How can I create a regex from a list of words?如何从单词列表中创建正则表达式?
【发布时间】:2013-02-03 10:18:48
【问题描述】:

我有一个单词字典(实际上我有嵌套的动词变位字典,但这不相关),我想通过组合它们来制作一个正则表达式。

{
  '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)?'

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

【问题讨论】:

  • 您是否尝试从字典中的值生成一个正则表达式?或者您是否尝试编写正则表达式来验证字典中的值。还是完全不同的东西?
  • 我想生成它。我的标签错了吗?
  • 有一个 JavaScript 库可以为您执行此操作:github.com/devongovett/regexgen(也许 Python 也有类似的东西?)

标签: python regex validation word


【解决方案1】:

我认为你需要有一个不那么聪明的方法

>>> 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'

如果你只是将哈希值与一个交替运算符连接起来,那么它应该做你想做的事

【讨论】:

  • 谢谢 Vorsprung :) 但是我有很多单词和其他变位(我给出的一个是不完美的变位,还有大约 15 个),我不想占用太多空间。但是是的,你的想法有效:)
  • 我总觉得电脑内存比我宝贵的时间便宜:)
  • 要保持简单,肯定有很多话要说!
  • @MalenaTorres:请将激励细节添加到上面的原始问题陈述中。它有所作为。另外,你真的想要字符最少的正则表达式吗? (或者只是一个利用共享前缀的相当优化的 '|' 分隔的串联列表?)
【解决方案2】:

是的,我相信这是可能的。

为了让您开始,这就是我将如何分解问题。

通过查找与所有拒绝值的开头匹配的最长可能字符串来计算根:

>>> 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

形成正则表达式是一件简单的事情,将根和括号中的 conjoined_endings 字符串结合起来:

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

【讨论】:

  • 谢谢@Johnsyweb,是的,这有帮助。但我不能投票给你 :( “需要 15 声望”。我可以接受你吗?
  • @MalenaTorres:不客气。希望这能让你开始,即使我的语言术语是关闭的。我很好奇您为什么要如此压缩正则表达式,您无需处理大量数据,更复杂的表达式只会增加您的验证时间。
  • 我让我的例子比它更简单,真的就像{'yo': '\w+aba'}, &c。最后我想比较不规则动词和规则的规则,我会有另一个像yo = {'imperfecto': '\w+aba', 'presente': '\w+o'}这样的字典。不过不规则动词更复杂,现在我只是从我的想法开始,看看我能做什么。
猜你喜欢
  • 2023-02-16
  • 1970-01-01
  • 2022-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-01
  • 1970-01-01
相关资源
最近更新 更多