如何在Python中解析特定子字符串旁边的值

如何在Python中解析特定子字符串旁边的值,python,regex,string,Python,Regex,String,我有一个日志文件,其中包含如下格式的行。我想解析子字符串element=(string)、time=(guint64)和ts=(guint64)旁边的值,并将它们保存到一个列表中,该列表将包含每行的单独列表: 0:00:00.336212023 62327 0x55f5ca5174a0 TRACE GST_TRACER :0:: element-latency, element-id=(string)0x55f5ca532a60, element=(string)rawv

我有一个日志文件,其中包含如下格式的行。我想解析子字符串
element=(string)
time=(guint64)
ts=(guint64)
旁边的值,并将它们保存到一个列表中,该列表将包含每行的单独列表:

0:00:00.336212023 62327 0x55f5ca5174a0 TRACE             GST_TRACER :0:: element-latency, element-id=(string)0x55f5ca532a60, element=(string)rawvideoparse0, src=(string)src, time=(guint64)852315, ts=(guint64)336203035;
0:00:00.336866520 62327 0x55f5ca5176d0 TRACE             GST_TRACER :0:: element-latency, element-id=(string)0x55f5ca53f860, element=(string)nvh264enc0, src=(string)src, time=(guint64)6403181, ts=(guint64)336845676;
最后的输出将如下所示:
['rawvideoparse0',8523153620035],'nvh264enc0',6403181336845676]


我可能应该使用Python的字符串拆分或分区方法来获取每行中的相关部分,但我无法找到一个简单的解决方案来概括我正在搜索的值。我也不知道如何处理这样一个事实:值
元素
时间
以逗号结尾,而
ts
以分号结尾(没有为这两种情况分别编写条件)。如何使用Python中的字符串操作方法实现这一点?

下面是一个可能的解决方案,使用一系列拆分命令:

output = []
with open("log.txt") as f:
    for line in f:
        values = []
        line = line.split("element=(string)", 1)[1]
        values.append(line.split(",", 1)[0])
        line = line.split("time=(guint64)", 1)[1]
        values.append(int(line.split(",", 1)[0]))
        line = line.split("ts=(guint64)", 1)[1]
        values.append(int(line.split(";", 1)[0]))
        output.append(values)

Regex就是为了这个:

lines = """
0:00:00.336212023 62327 0x55f5ca5174a0 TRACE             GST_TRACER :0:: element-latency, element-id=(string)0x55f5ca532a60, element=(string)rawvideoparse0, src=(string)src, time=(guint64)852315, ts=(guint64)336203035;
0:00:00.336866520 62327 0x55f5ca5176d0 TRACE             GST_TRACER :0:: element-latency, element-id=(string)0x55f5ca53f860, element=(string)nvh264enc0, src=(string)src, time=(guint64)6403181, ts=(guint64)336845676;
"""

import re

pattern = re.compile(".*element-id=\\(string\\)(?P<elt_id>.*), element=\\(string\\)(?P<elt>.*), src=\\(string\\)(?P<src>.*), time=\\(guint64\\)(?P<time>.*), ts=\\(guint64\\)(?P<ts>.*);")
for l in lines.splitlines():
    match = pattern.match(l)
    if match:
        results = match.groupdict()
        print(results)
您可以使这个正则表达式模式更加通用,因为所有元素都共享一个公共结构
=()


请注意,在所有情况下,您都是调试正则表达式的朋友:)

这不是最快的解决方案,但为了可读性,我可能会这样编写它

# create empty list for output
list_final_output = []

# filter substrings
list_filter = ['element=(string)', 'time=(guint64)', 'ts=(guint64)']

# open the log file and read in the lines as a list of strings
with open('so_58272709.log', 'r') as f_log:
    string_example = f_log.read().splitlines()
print(f'string_example: \n{string_example}\n')

# loop through each line in the list of strings
for each_line in string_example:

    # split each line by comma
    list_split_line = each_line.split(',')

    # loop through each filter substring, include filter
    filter_string = [x for x in list_split_line if (list_filter[0] in x
                                                    or list_filter[1] in x
                                                    or list_filter[2] in x
                                                   )]

    # remove the substring
    filter_string = [x.replace(list_filter[0], '') for x in filter_string]
    filter_string = [x.replace(list_filter[1], '') for x in filter_string]
    filter_string = [x.replace(list_filter[2], '') for x in filter_string]

    # store results of each for-loop
    list_final_output.append(filter_string)

# print final output
print(f'list_final_output: \n{list_final_output}\n')

要么使用正则表达式,要么使用一系列拆分命令。到目前为止你尝试了什么?
pattern2 = re.compile("(?P<name>[^,;\s]*)=\\((?P<type>[^,;]*)\\)(?P<value>[^,;]*)")
for l in lines.splitlines():
    all_interesting_items = pattern2.findall(l)
    print(all_interesting_items)
[]
[('element-id', 'string', '0x55f5ca532a60'), ('element', 'string', 'rawvideoparse0'), ('src', 'string', 'src'), ('time', 'guint64', '852315'), ('ts', 'guint64', '336203035')]
[('element-id', 'string', '0x55f5ca53f860'), ('element', 'string', 'nvh264enc0'), ('src', 'string', 'src'), ('time', 'guint64', '6403181'), ('ts', 'guint64', '336845676')]
# create empty list for output
list_final_output = []

# filter substrings
list_filter = ['element=(string)', 'time=(guint64)', 'ts=(guint64)']

# open the log file and read in the lines as a list of strings
with open('so_58272709.log', 'r') as f_log:
    string_example = f_log.read().splitlines()
print(f'string_example: \n{string_example}\n')

# loop through each line in the list of strings
for each_line in string_example:

    # split each line by comma
    list_split_line = each_line.split(',')

    # loop through each filter substring, include filter
    filter_string = [x for x in list_split_line if (list_filter[0] in x
                                                    or list_filter[1] in x
                                                    or list_filter[2] in x
                                                   )]

    # remove the substring
    filter_string = [x.replace(list_filter[0], '') for x in filter_string]
    filter_string = [x.replace(list_filter[1], '') for x in filter_string]
    filter_string = [x.replace(list_filter[2], '') for x in filter_string]

    # store results of each for-loop
    list_final_output.append(filter_string)

# print final output
print(f'list_final_output: \n{list_final_output}\n')