攝影或3C

正則表示法(Regular Expression): 如何使用命名捕獲組將字串整理為dict?match.groupdict() ; NAME: sensor-count STATUS: PASSED VALUE: 129 LL: 129 UL:

# -*- coding: utf-8 -*-
"""
Created on Fri Jun 06 08:13:12 2024

@author: SavingKing
"""

import re
import pandas as pd

def strr2dict(strr) -> dict:
    """
    Parameters
    ----------
    strr : str
        日誌字符串例如:
        ' 2024-02-19 11:44:43,179 INFO - [opentest_boost.process_steps.boosted_step:987] MEASUREMENT >>> NAME: sensor-count STATUS: PASSED VALUE: 129 LL: 129 UL: '

    Returns
    -------
    dict
        解析後的字典例如:
        {'name': 'sensor-count', 'status': 'PASSED', 'value': '129', 'll': '129', 'ul': ''}
    """
    strr_end = strr.split(">>>")[-1].lstrip()
    
    pattern = re.compile(
        r'NAME: (?P<name>[\w-]+) STATUS: (?P<status>\w+) VALUE: (?P<value>[\d.-]*) (LL: (?P<ll>[\d.-]*) )?(UL: (?P<ul>[\d.-]*))?'
    )
    """
        pattern = re.compile(
        r'NAME: (?P<name>[\w-]+) STATUS: (?P<status>\w+) VALUE: (?P<value>[\d.-]*) LL: (?P<ll>[\d.-]*)? UL: (?P<ul>[\d.-]*)?'
    )
    """
    match = pattern.search(strr_end)
    
    if match:
        log_dict = match.groupdict()
        return log_dict
    else:
        print(f"Regular expression not found in {strr_end}")
        return {}

def parse_logs(wanted):
    """
    解析日誌列表並返回包含字典的列表

    Parameters
    ----------
    wanted : list
        包含日誌字符串的列表

    Returns
    -------
    list
        包含解析後的字典的列表
    """
    lis_json = []
    for strr in wanted:
        log_dict = strr2dict(strr)
        lis_json.append(log_dict)
    return lis_json

# 示例用法
wanted = [
    '2024-02-19 11:44:43,179 INFO - [opentest_boost.process_steps.boosted_step:987] MEASUREMENT >>> NAME: fan3-tach STATUS: PASSED VALUE: 7021.0 LL: 3500 UL: 7500',
    '2024-02-19 11:44:44,179 INFO - [opentest_boost.process_steps.boosted_step:988] MEASUREMENT >>> NAME: fan4-pwm STATUS: PASSED VALUE: 30.0 LL: 27 UL: 33',
    '2024-02-19 11:44:45,179 INFO - [opentest_boost.process_steps.boosted_step:989] MEASUREMENT >>> NAME: fan4-tach STATUS: PASSED VALUE: 7072.0 LL: 3500 UL: 7500',
    '2024-02-19 11:44:46,179 INFO - [opentest_boost.process_steps.boosted_step:990] MEASUREMENT >>> NAME: fan5-pwm STATUS: PASSED VALUE: 30.0 LL: 27 UL: 33',
    '2024-02-19 11:44:47,179 INFO - [opentest_boost.process_steps.boosted_step:991] MEASUREMENT >>> NAME: fan5-tach STATUS: PASSED VALUE: 7021.0 LL: 3500 UL: 7500',
    '2024-02-19 11:44:48,179 INFO - [opentest_boost.process_steps.boosted_step:992] MEASUREMENT >>> NAME: i2cool-rear STATUS: PASSED VALUE: 26.898 LL: 15 UL: 45',
    '2024-02-27 11:25:05,010 INFO - [opentest_boost.process_steps.boosted_step:993] MEASUREMENT >>> NAME: current-3r3-pe-d-vr-iout STATUS: PASSED VALUE: -0.099 LL:  UL:']

for dic in parse_logs(wanted):
    print(dic)

輸出結果:

正則表達式

pattern = re.compile(
    r'NAME: (?P<name>[\w-]+) STATUS: (?P<status>\w+) VALUE: (?P<value>[\d.-]*) LL: (?P<ll>[\d.-]*)? UL: (?P<ul>[\d.-]*)?'
)

逐部分解释

  1. r'...':
    • 字符串前的 r 表示这是一个原始字符串(raw string),这样在字符串中反斜杠 \ 不需要被转义。
  2. NAME: (?P<name>[\w-]+):
    • NAME:: 匹配字符串 “NAME:”。
    • (?P<name>[\w-]+): 命名捕获组,名称为 name
      • (?P<name>...): 定义了一个命名捕获组,组名为 name
      • [\w-]+: 匹配一个或多个字母、数字、下划线或连字符。\w 等价于 [a-zA-Z0-9_]
  3. STATUS: (?P<status>\w+):
    • STATUS:: 匹配字符串 “STATUS:”。
    • (?P<status>\w+): 命名捕获组,名称为 status
      • (?P<status>...): 定义了一个命名捕获组,组名为 status
      • \w+: 匹配一个或多个字母、数字或下划线。
  4. VALUE: (?P<value>[\d.-]*):
    • VALUE:: 匹配字符串 “VALUE:”。
    • (?P<value>[\d.-]*): 命名捕获组,名称为 value
      • (?P<value>...): 定义了一个命名捕获组,组名为 value
      • [\d.-]*: 匹配零个或多个数字、点或连字符。\d 等价于 [0-9]
  5. LL: (?P<ll>[\d.-]*)?:
    • LL:: 匹配字符串 “LL:”。
    • (?P<ll>[\d.-]*)?: 命名捕获组,名称为 ll,并且整个捕获组是可选的。
      • (?P<ll>...): 定义了一个命名捕获组,组名为 ll
      • [\d.-]*: 匹配零个或多个数字、点或连字符。
      • ?: 表示前面的整个捕获组是可选的,可以出现零次或一次。
  6. UL: (?P<ul>[\d.-]*)?:
    • UL:: 匹配字符串 “UL:”。
    • (?P<ul>[\d.-]*)?: 命名捕获组,名称为 ul,并且整个捕获组是可选的。
      • (?P<ul>...): 定义了一个命名捕获组,组名为 ul
      • [\d.-]*: 匹配零个或多个数字、点或连字符。
      • ?: 表示前面的整个捕获组是可选的,可以出现零次或一次。

解释总结

这个正则表达式模式用于匹配类似以下格式的字符串:

NAME: tmp461-front-inlet STATUS: OK VALUE: 25.5 LL: 20.0 UL: 30.0

具体匹配内容和对应的命名捕获组为:

NAME: 匹配 tmp461-front-inlet 到 name 捕获组。
STATUS: 匹配 OK 到 status 捕获组。
VALUE: 匹配 25.5 到 value 捕获组。
LL: 匹配 20.0 到 ll 捕获组(可选)。
UL: 匹配 30.0 到 ul 捕获组(可选)。
通过使用命名捕获组和 groupdict() 方法,可以轻松地将匹配的子字符串提取到一个字典中,便于后续处理。
儲蓄保險王

儲蓄險是板主最喜愛的儲蓄工具,最喜愛的投資理財工具則是ETF,最喜愛的省錢工具則是信用卡