【问题标题】:How can I allow a fuzzy regex match for only part of the pattern?如何仅允许部分模式进行模糊正则表达式匹配?
【发布时间】:2019-08-07 04:07:45
【问题描述】:

我有一个pattern_string = 'ATAG/GAGAAGATGATG/TATA' 和一个query_string = 'ATAG/AGCAAGATGATG/TATA'。这适用于以下正则表达式匹配:

r = regex.compile('(%s){e<=2}' % pattern_string)

r.match(query_string)

这里,唯一的变化是两个/ 字符之间。但是,我想限制匹配的模糊性,只允许在这些字符之间,而/ 边界之外的字符仍然是完全匹配的。

例如,pattern_string = 'ATGG/GAGAAGATGATG/TATA' 和 query_string = 'ATAG/AGCAAGATGATG/TATA'不 匹配,因为字符串的第一部分(ATGG 与 ATAG)不匹配。同样,pattern_string = 'ATAG/GAGAAGATGATG/TATG' 和 query_string = 'ATAG/AGCAAGATGATG/TATA' 也不匹配,因为字符串的最后一部分(TATG vs TATA)不匹配。

总之,/(或任何分隔符)内的字符串部分应允许根据正则表达式(在本例中为{e&lt;=2})指定的内容进行模糊匹配,但外部的字符串必须完全匹配。

如何做到这一点?

我正在想象一个类似下面的函数

ideal_function(pattern_string, query_string)

在哪里

ideal_function(pattern_string = 'ATAG/GAGAAGATGATG/TATA', query_string = 'ATAG/AGCAAGATGATG/TATA') 返回True ideal_function(pattern_string = 'ATGG/GAGAAGATGATG/TATA', query_string = 'ATAG/AGCAAGATGATG/TATA') 返回False

最有效的方法将不胜感激,我必须对超过 20,000 个模式字符串和超过 500 万个查询字符串的组合执行此操作,因此它需要尽可能高效。它不一定必须是正则表达式解决方案,但它必须支持允许对指定的替换计数(如{s&lt;=2})和错误计数(如{e&lt;=2})进行模糊匹配的选项。

【问题讨论】:

  • 查询字符串中是否总是只有两个斜杠?可以有一个吗?根本没有斜线?

标签: python regex python-3.x fuzzy-search


【解决方案1】:

您可以使用以下您想要的ideal_function() 实现将模糊性限制在斜线之间的模式部分:

def ideal_function(pattern_string, query_string, fuzzy='e<=2'):
    prefix, body, suffix = pattern_string.split('/')
    r = regex.compile('%s/(%s){%s}/%s' % (prefix, body, fuzzy, suffix))
    return r.match(query_string) is not None

它在行动:

>>> ideal_function('ATAG/GAGAAGATGATG/TATA', 'ATAG/AGCAAGATGATG/TATA')
True

>>> ideal_function('ATGG/GAGAAGATGATG/TATA', 'ATAG/AGCAAGATGATG/TATA')
False

>>> ideal_function('ATAG/GAGAAGATGATG/TATA', 'ATAG/AGCAAGATGATG/TATA', 'e<=1')
False

>>> ideal_function('ATAG/GAGAAGATGATG/TATA', 'ATAG/AGCAAGATGATG/TATA', 'e<=2')
True

>>> ideal_function('ATAG/GAGAAGATGATG/TATA', 'ATAG/AGCAAGATGATG/TATA', 's<=2')
False

>>> ideal_function('ATAG/GAGAAGATGATG/TATA', 'ATAG/AGCAAGATGATG/TATA', 's<=3')
True

这依赖于您在模式中始终恰好有三个斜线分隔的部分,但由于任何更通用的内容还需要指定哪些部分是模糊的,哪些部分是非模糊的,我认为这种简单的方法适合您的用例。

顺便说一下,任何版本的ideal_function() 每次调用时都必须创建适当的正则表达式,这可能不是最有效的方法(尽管您必须进行一些分析以确定多少它在您的特定情况下实际产生的差异)。

根据您需要的输出类型,像这样可能更有意义:

def ideal_generator(pattern_string, all_query_strings, fuzzy='e<=2'):
    prefix, body, suffix = pattern_string.split('/')
    r = regex.compile('%s/(%s){%s}/%s' % (prefix, body, fuzzy, suffix))
    for query_string in all_query_strings:
        if r.match(query_string) is not None:
            yield query_string

...这将产生与pattern_string匹配的所有查询字符串。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-24
    • 1970-01-01
    • 2011-07-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多