在Python中解析字符串输入的更好方法?

时间:2017-01-29 14:23:58

标签: python regex

我正在制作一个根据用户输入(字符串)输出不同信息的机器人。我想知道是否有更好的方法来解析输入并重定向到不同的结果:

def query(msg: str):
    if re.compile(r"moci(o|ó)?n(es)? de (procedimiento)s?", re.IGNORECASE).search(msg):
        return open("mociones/mocion_procedimiento.txt", "r").read()

    elif re.compile(r"moci(o|ó)?n(es)? de (ó|o)?rden(es)?", re.IGNORECASE).search(msg):
        return open("mociones/mocion_orden.txt", "r").read()

    elif re.compile(r"moci(o|ó)?n(es)? de duda(s)?", re.IGNORECASE).search(msg):
        return open("mociones/mocion_duda.txt", "r").read()

    elif re.compile(r"moci(o|ó)?n(es)? de privilegio(s)?", re.IGNORECASE).search(msg):
        return open("mociones/mocion_privilegio.txt", "r").read()

    ...

    elif re.compile(r"defender (el|los)? anteproyectos?", re.IGNORECASE).search(msg):
        return open("debate_particular/index.txt", "r").read()

    elif re.compile(r"anteproyectos?", re.IGNORECASE).search(msg):
        return open("anteproyecto/index.txt", "r").read()

    else:
        return "_*ERROR*_\n\nNo search results were found for \n`{query}`".format(query=msg)

2 个答案:

答案 0 :(得分:2)

一个明显的建议是使用dict regex => path并使用循环而不是一堆if语句:

paths = {
    r"(?i)moci[oó]?n(es)? de (procedimiento)s?": "mociones/mocion_procedimiento.txt",
    r"(?i)moci[oó]?n(es)? de [óo]?rden(es)?": "mociones/mocion_orden.txt"
}

def path_for_msg(msg):
    for r, p in paths.items():
        if re.search(r, msg):
            return p

如果需要,re.compile也很难,因为re负责在幕后进行编译。

如果顺序很重要,那么正确的数据结构就是元组列表:

paths = [
    (r"(?i)moci[oó]?n(es)? de (procedimiento)s?", "mociones/mocion_procedimiento.txt"),
    (r"(?i)moci[oó]?n(es)? de [óo]?rden(es)?", "mociones/mocion_orden.txt")
}

def path_for_msg(msg):
    for r, p in paths:
        if re.search(r, msg):
            return p

答案 1 :(得分:0)

另一种方法是采用更加面向对象的方法,创建单独的类来处理不同类型的输入并将它们安排到一个责任链中 - 类似于georg的建议,除了你要迭代消息处理程序对象而不是原始正则表达式模式。

有关详细信息,请参阅this answer