【问题标题】:Python Emulate strptime behavorPython 模拟 strptime 行为
【发布时间】:2014-07-14 13:27:03
【问题描述】:

我有一个 python 程序,它从许多来源获取文件,来自同一来源的所有文件具有相同的格式,但格式差异很大。一个来源可以是 ServerName - ProccessID - Date 格式,另一个来源可以是 (Date)_Username_ProccessID_Server。目前,要使用新格式添加新源,需要编码人员为每个源编写解析函数。

我已经开始编写一个新的适配器,我想将文件格式存储为一个字符串。第一个可能是 %S - %P - %D,第二个可能是 (%D)%U%P_%S。

在 python3 中最好的方法是什么?

【问题讨论】:

    标签: python python-3.x string-parsing


    【解决方案1】:

    这样的事情是合理的:

    import re
    from collections import namedtuple
    
    Format = namedtuple('Format', 'name format_string regex')
    class Parser(object):
        replacements = [Format('server', '%S', r'[A-Za-z0-9]+'),
                        Format('user', '%U', r'[A-Za-z0-9]+'),
                        Format('date', '%D', r'[0-9]{4}-[0-9]{2}-[0-9]{2}'),
                        Format('process_id', '%P', r'[0-9]+'),
                        ]
    
        def __init__(self, format):
            self.format = format
            self.re = re.compile(self._create_regex(format))
    
        def _create_regex(self, format):
            format = re.escape(format)
            for replacement in self.replacements:
                format = format.replace(r'\%s' % replacement.format_string,
                                        r'(?P<%s>%s)' % (replacement.name,
                                                         replacement.regex,
                                                         ),
                                        )
            return format
    
        def parse(self, data):
            match = self.re.match(data)
            if match:
                return match.groupdict()
            return None
    

    用法:

    a_parser = Parser("(%D)%U_%P_%S")
    print a_parser.parse("(2005-04-12)Jamie_123_Server1")
    
    b_parser = Parser("%S - %P - %D")
    print b_parser.parse("Server1 - 123 - 2005-04-12")
    

    输出:

    {'date': '2005-04-12', 'process_id': '123', 'user': 'Jamie', 'server': 'Server1'}
    {'date': '2005-04-12', 'process_id': '123', 'server': 'Server1'}
    

    本质上,我在您的自定义格式语法中的%?s 和预定义的正则表达式之间创建一个映射以匹配该参数,然后用相应的正则表达式替换给定格式字符串中的%? 字符串以构建该模式的解析器。

    仅当在格式字符串中分隔“类型”的字符没有出现在它的正则表达式中,或者如果没有分隔符,那么这两个并排的正则表达式不“互相干扰”。例如,使用格式字符串:

    %U%P
    

    而我在上面分配给userprocess_id 的正则表达式,无法分辨user 的结束位置和process_id 的开始位置:

    User1234
    

    User1234 还是User1234,或任何其他组合?但是,即使是人类也无法解决这个问题!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-08
      • 2010-10-25
      • 1970-01-01
      • 2013-09-08
      • 1970-01-01
      • 2011-03-19
      • 1970-01-01
      相关资源
      最近更新 更多