【问题标题】:Regex fuzzy word match正则表达式模糊词匹配
【发布时间】:2014-12-16 00:29:01
【问题描述】:

棘手的正则表达式问题:我想使用正则表达式从有关镇压的新闻句子中提取信息。以下是一些示例:

doc1 = "5 young students arrested"
doc2 = "10 rebels were reported killed"

我想根据实体和结果列表匹配句子:

entities = ['students','rebels']
outcomes = ['arrested','killed']

如何使用正则表达式提取 0-99999 的参与者数量、任何实体、任何结果,同时忽略随机文本(例如“年轻”或“被报告”)?这就是我所拥有的:

re.findall(r'\d{1,5} \D{1,50}'+ '|'.join(entities) + '\D{1,50}' + '|'.join(outcomes),doc1)

即一个数字、一些可选的随机文本、一个实体、一些更多的可选随机文本和一个结果。 出了点问题,我认为是因为 OR 语句。感谢您的帮助!

【问题讨论】:

  • 这是自然语言处理中的常见任务。你应该用谷歌搜索一下,看看它是如何在 Python 中正确完成的。我过去使用过 Stanford Parser (Java),这为我节省了很多时间:nlp.stanford.edu/software/lex-parser.shtml
  • 这不是你应该纯粹用正则表达式做的事情
  • 作为替代解决方案,您可以查看 nltk。它提供了标记单词的功能(用语法信息注释单词),然后您可以查找实体、被动语态和数字的组合。
  • 感谢您的快速解答! @ReutSharabani,当您知道感兴趣的特定实体和操作时,即使使用定制的应用程序,Stanford Parser 是否更好?我认为可能不是,但我可能(肯定)是错的。
  • @user1060859,虽然您可以使用正则表达式进行快速破解,但如果它只是您正在研究的东西 - NLP 工具是正确的工具。您需要进行词干提取、句子提取、标记化、忽略语法错误等等。这些都已经被专业人士解决了,为什么还要再解决呢? 使用nltk

标签: python regex parsing information-extraction


【解决方案1】:

这个正则表达式应该匹配你的两个例子:

pattern = r'\d+\s+.*?(' + '|'.join(entities) + r').*?(' + '|'.join(outcomes) + ')'

您缺少的是 OR 周围的括号。

但是,仅使用正则表达式可能不会给您带来好的结果。考虑使用解析句子的自然语言处理库,如 NLTK

【讨论】:

    【解决方案2】:

    正如@ReutSharabani 已经回答的那样,这不是进行 nlp 的正确方法,但这回答了字面问题。

    正则表达式应为:

    import re;
    entities = ['students','rebels'];
    outcomes = ['arrested','killed'];
    p = re.compile(r'(\d{1,5})\D{1,50}('+'|'.join(entities)+')\D{1,50}('+'|'.join(outcomes)+')');
    m = p.match(doc1);
    number = m.group(1);
    entity = m.group(2);
    outcome = m.group(3);
    

    您忘记将您的 OR 操作分组 ()。相反,您生成的是a|b|\W|c|d|\W(短版)。

    【讨论】:

    • \D{1,50} 的注释:这些词是可选的(例如doc2 的开头)
    • \D 也可以匹配空格。我猜OP只是想限制范围。如果5students 之间的跨度超过50 个字符,则两者之间的关联可能性很小。
    【解决方案3】:

    你应该试试regex 模块! 它内置了模糊匹配功能。其他答案似乎更加健壮和时尚,但这也可以通过模糊匹配来完成!

    pattern = r'\d{1,5}(%(entities)s)(%(outcomes)s){i}' %{'entities' : '|'.join(entities), 'outcomes' : '|'.join(outcomes)}
    regex.match(pattern, news_sentence)
    

    这里发生的情况是 {i} 表示您想要匹配任意数量的插入。这里的问题是它可以将字符插入到实体或结果之一中,并且仍然产生匹配。如果您想接受对任何结果或实体的拼写的细微更改,那么您也可以使用 {e

    【讨论】:

    • 我误读了原来的问题!这不是一个好的答案,但仍然是一个有用的工具。我认为您想要做的只是收集 的所有实例,允许任何不是介于两者之间的句点,即 [^.]*,然后使用 re.sub排除所有不是实体、数字或结果的东西。
    猜你喜欢
    • 1970-01-01
    • 2013-01-04
    • 2016-05-29
    • 2015-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    • 2018-12-16
    相关资源
    最近更新 更多