【问题标题】:regular expression dictionary [Google type search and match with regular expressions]正则表达式字典【谷歌类型搜索和正则表达式匹配】
【发布时间】:2013-04-14 16:44:56
【问题描述】:

编辑: 下面代码的主要问题之一是由于将正则表达式对象存储在字典中,以及如何访问它们以查看它们是否可以匹配另一个细绳。但我仍然会留下我之前的问题,因为我认为可能有一种简单的方法可以完成所有这些操作。

我想在 python 中找到一个方法,它知道如何返回两个字符串是否引用同一事物的布尔值。我知道这很困难,如果在编程中不是完全荒谬的话,但我正在研究使用引用同一事物的替代字符串字典来处理这个问题。

这里有一些例子,因为我知道没有它们就没有多大意义。

如果我给出字符串:

'breakingBad.Season+01 Episode..02'

那我想让它匹配字符串:

'Breaking Bad S01E02'

或者'three.BuCkets+of H2O'可以匹配'3 buckets of water'

我知道这几乎是不可能做到的,因为 '3''water' 等是同义词,但如果需要,我愿意将这些作为相关正则表达式同义词的字典提供给函数。

我感觉在 python 中有一种更简单的方法可以做到这一点,就像往常一样,但这是我目前所拥有的:

import re

def check_if_match(given_string, string_to_match, alternative_dictionary):
    print 'matching: ', given_string, '  against: ', string_to_match
    # split the string into it's parts with pretty much any special character 
    list_of_given_strings = re.split(' |\+|\.|;|,|\*|\n', given_string)
    print 'List of words retrieved from given string: '
    print list_of_given_strings
    check = False
    counter = 0
    for i in range(len(list_of_given_strings)):
        m = re.search(list_of_given_strings[i], string_to_match, re.IGNORECASE)
        m_alt = None
        try:
            m_alt = re.search(alternative_dictionary[list_of_given_strings[i]], string_to_match, re.IGNORECASE)
        except KeyError:
            pass
        if m or m_alt:
            if counter == len(list_of_given_strings)-1: check = True
            else: counter += 1
            print list_of_given_strings[i], ' found to match'
        else:
            print list_of_given_strings[i], ' did not match'
            break
    return check

string1 = 'breaking Bad.Season+01 Episode..02'
other_string_to_check = 'Breaking.Bad.S01+E01'
# make a dictionary of synonyms -  here we should be saying that "S01" is equivalent to "Season 01"
alternative_dict = {re.compile(r'S[0-9]',flags=re.IGNORECASE):re.compile(r'Season [0-9]',flags=re.IGNORECASE),\
                    re.compile(r'E[0-9]',flags=re.IGNORECASE):re.compile(r'Episode [0-9]',flags=re.IGNORECASE)}
print check_if_match(string1, other_string_to_check, alternative_dict)
print 
# another try
string2 = 'three.BuCkets+of H2O'
other_string_to_check2 = '3 buckets of water'
alternative_dict2 = {'H2O':'water', 'three':'3'}
print check_if_match(string2, other_string_to_check2, alternative_dict2)

这会返回:

matching:  breaking Bad.Season+01 Episode..02   against:  Breaking.Bad.S01+E01
List of words retrieved from given string: 
['breaking', 'Bad', 'Season', '01', 'Episode', '', '02']
breaking  found to match
Bad  found to match
Season  did not match
False

matching:  three.BuCkets+of H2O   against:  3 buckets of water
List of words retrieved from given string: 
['three', 'BuCkets', 'of', 'H2O']
three  found to match
BuCkets  found to match
of  found to match
H2O  found to match
True

我意识到这可能意味着我的字典键和值有问题,但我觉得我离可能已经创建的简单 pythonic 解决方案越来越远了。

有人有什么想法吗?

【问题讨论】:

    标签: python regex search dictionary full-text-search


    【解决方案1】:

    我正在修补它,发现了一些有趣的东西:

    • 这可能与您将初始单词分解为列表的方式有关

      matching:  breaking Bad.Season 1.Episode.1   against:  Breaking.Bad.S1+E1
      List of words retrieved from given string:
      ['breaking', 'Bad', 'Season', '1', 'Episode', '1']
      
    • 我认为您希望它是 ..., 'Season 1', ...,而不是让 'Season'1 在列表中成为单独的条目。

    • 您指定了S[0-9],但这不会匹配两位数。

    • 您的常规表达式存储在字典中是正确的;映射仅适用于一个方向。我通过将r'Season [0-9]' 映射到r'S[0-9]' 而不是反之亦然来摆弄代码(不幸的是不记得它是什么),它能够匹配Season

    建议

    • 不是映射,而是为每个字符串类型(例如标题、季节、剧集)设置一个等价类,并为此设置一些匹配器代码。
    • 分离解析和比较步骤。将每个字符串单独解析为通用格式或对象,然后进行比较
    • 您可能需要实现某种状态机才能知道您正在处理一个赛季,并希望在其后立即看到一个特定格式的数字。
    • 您可能想改用第三方工具;我听说过关于Renamer 的好消息

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-17
      • 1970-01-01
      • 2017-12-21
      • 2017-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多