【问题标题】:How do I grab the last portion of a log string and interpret it as json?如何获取日志字符串的最后一部分并将其解释为 json?
【发布时间】:2017-06-03 02:52:38
【问题描述】:

我正在查看以下格式的日志消息

datetime log_message_type message_type server {json_string}

所以每一行用空格分隔,每行总是有相同的字段,最后有一个json字符串,json块内有各种字段。

我想过用一个简单的方法来做这个

with open('test.log', 'r') as f:
    for x in f:
        line = x.split()

        datetime         = line[0]
        log_message_type = line[1]
        message_type     = line[2]
        server           = line[3]
        json_string      = line[4]

这本来可以的,除非我的 json 字符串中有空格,例如,像这样的东西。

{ "foo" : "bar" }

因此以这种方式执行此操作会在空格处拆分我的 json 字符串。有什么方法可以使用正则表达式或其他东西在空格上拆分,直到我到达该行的“json string”部分,然后保留其余部分?我尝试做类似的事情

line = re.compile(".*\s.*\s.*\s.*\s").split(x)

尝试根据 json 字符串部分之前的 4 个空格来解析该行,但恐怕我对 python 中的正则表达式系统如何工作还不够了解。谁能帮我一把?

编辑:忘了提,为此我坚持使用 python 2.7。

【问题讨论】:

    标签: python json regex


    【解决方案1】:

    限制拆分次数:

    line = x.split(maxsplit=4)
    
    >>> "a b c d my json expression".split(maxsplit=4)
    ['a', 'b', 'c', 'd', 'my json expression']
    

    注意:python 2 参数不同,您必须将 then 作为位置传递(也适用于 python 3 BTW):

    line = x.split(None,4)
    

    【讨论】:

    • 应该是 4 而不是 3
    • 是的,已修复。我先放 4,然后放 3,但再次阅读问题,是 4
    • 我假设仅适用于 python 3? :(
    • "split 不接受关键字参数"
    【解决方案2】:

    这样的事情怎么样?

    line = "datetime log_message_type message_type server {json_string}" 
    
    re.search(r"(\S+) (\S+) (\S+) (\S+) {(\S+)}", line).groups()
    

    输出:

    ('datetime', 'log_message_type', 'message_type', 'server', 'json_string')
    

    【讨论】:

    • NoneType 没有元素组
    • 我已经编辑了我的答案。我在这个示例字符串上使用了它。
    • 使用 python 2.7 或 3+?
    • 用过的python 3.5
    • 不幸的是,我的结果相同。我使用的是 2.7
    【解决方案3】:

    如果您使用的是 python 3,则可以利用 extended iterable unpacking

    long_string = "example example test test test test test test"
    x1, x2, *tests = long_string.split()
    tests = ' '.join(tests)
    print(tests)
    #test test test test test test
    

    【讨论】:

    • 这种方法的问题是当long_string = "example example test test test test 'test test'":您通过仅用一个空格连接来破坏带引号的字符串的信息。快速修复将是做long_string.split(" ")(只有一个空格)所以加入是双射的。
    【解决方案4】:

    试试这样的。正则表达式很快就会失控。

    log_line = "datetime log_message_type message_type server {json_string}"
    json_part = log_line.split(None, 4)[-1]
    

    【讨论】:

    • 认为我会接受这个,这似乎是 python 2 最简洁和可行的
    • 感谢您。考虑到我的 python 2.7 限制,这是最可行的。
    • 不客气。 sn-p 也适用于 Python 3。
    猜你喜欢
    • 1970-01-01
    • 2020-09-14
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 2021-04-13
    • 2018-03-06
    • 2018-07-08
    相关资源
    最近更新 更多