当前位置: 首页 > news >正文

《从 0 到 1 掌握正则表达式:解析串口数据的万能钥匙》

引语

在物联网开发的世界里,串口数据如同流淌的数字血液,每一行字符都藏着环境监测的秘密。当你面对[321022] T:25 C H:68% L:0%这样的数据流时,正则表达式就像一把精准的瑞士军刀 —— 它能从混乱的字符中切割出时间戳、温度、湿度等关键信息,让 STM32 传感器的数据乖乖 “对号入座”。

本文将带你拆解正则表达式的核心语法,从\d+匹配数字到()捕获组提取数据,再到通过re.match()从字符串开头精准锁定目标。无论你是想解析气象监测数据,还是开发传感器数据管理系统,掌握这把 “数字手术刀”,就能让每一行串口输出都成为可解读的洞察,让代码在数据洪流中开辟出清晰的航道。

点关注不迷路哟。你的点赞、收藏,一键三连,是我持续更新的动力哟!!!

主页:

一位搞嵌入式的 genius-CSDN博客https://blog.csdn.net/m0_73589512?spm=1000.2115.3001.5343

目录

python自动化采集数据脚本:常用函数解析

1. fetchone(self) 方法解析

功能说明

使用场景

2. execute(self, query, args=None) 方法解析

功能说明

使用场景

3. commit(self) 方法解析

功能说明

使用场景

4. 整体逻辑总结

游标工作流程示例

5. 扩展知识:游标与连接的关系

6. 正则表达式基本语法规则

7. 正常数据正则表达式解析

模式分解说明

匹配示例

8. 错误数据正则表达式解析

模式分解说明

匹配示例

9. 正则表达式核心元字符说明

10. 扩展:正则表达式进阶写法

1. 匹配小数温度(如 25.5°C)

2. 匹配更灵活的空白字符

3. 添加行首尾匹配

11. 正则表达式测试方法

测试步骤

12. 正则表达式最佳实践

13. 函数 match(pattern, string, flags=0) 解析

一、函数功能概述

二、参数详解

三、实现逻辑解析

四、与其他匹配函数的对比

五、flags 参数常用取值

六、Match 对象常用方法和属性

七、使用场景建议

八、注意事项

python自动化采集数据脚本:常用函数解析

1. fetchone(self) 方法解析
def fetchone(self):"""Fetch the next row."""self._check_executed()if self._rows is None or self.rownumber >= len(self._rows):return Noneresult = self._rows[self.rownumber]self.rownumber += 1return result
功能说明
  • 获取查询结果的下一行数据:从结果集中按顺序获取一行数据

  • 关键逻辑:

    1. self._check_executed():检查是否已执行查询(防止未查询就获取数据)

    2. 检查结果集是否存在(self._rows is None)或是否已取完数据(rownumber >= len(self._rows)

    3. 若数据存在,返回当前行(self._rows[self.rownumber])并将行号(rownumber)加 1

  • 返回值:

    • 成功:返回结果集中的下一行数据(元组或字典)

    • 失败:返回None(无更多数据或查询未执行)

使用场景
  • 逐行处理查询结果(如需要控制数据读取节奏时)

  • 示例:

    cursor.execute("SELECT * FROM users")
    row = cursor.fetchone()
    while row:print(row)row = cursor.fetchone()
2. execute(self, query, args=None) 方法解析
def execute(self, query, args=None):"""Execute a query.
​:param query: Query to execute.:type query: str
​:param args: Parameters used with query. (optional):type args: tuple, list or dict
​:return: Number of affected rows.:rtype: int"""while self.nextset():pass
​query = self.mogrify(query, args)
​result = self._query(query)self._executed = queryreturn result
功能说明
  • 执行 SQL 查询语句:接收 SQL 查询和参数,执行后返回受影响的行数

  • 关键逻辑:

    1. while self.nextset(): pass:跳过之前查询的结果集(处理多结果集场景)

    2. query = self.mogrify(query, args):将参数绑定到 SQL 查询中(防 SQL 注入)

    3. result = self._query(query):执行实际的查询操作

    4. 记录已执行的查询(self._executed = query)并返回受影响行数

  • 参数说明:

    • query:SQL 查询语句(如SELECT * FROM users WHERE id = %s

    • args:查询参数(支持tuple/list(对应%s)或dict(对应%(name)s))

使用场景
  • 执行增删改查操作(INSERT/UPDATE/DELETE/SELECT)

  • 示例:

    # 使用tuple参数
    cursor.execute("INSERT INTO users(name, age) VALUES(%s, %s)", ("张三", 25))
    ​
    # 使用dict参数
    cursor.execute("SELECT * FROM users WHERE age > %(min_age)s", {"min_age": 18})
3. commit(self) 方法解析
def commit(self):"""Commit changes to stable storage.
​See `Connection.commit() <https://www.python.org/dev/peps/pep-0249/#commit>`_in the specification."""self._execute_command(COMMAND.COM_QUERY, "COMMIT")self._read_ok_packet()
功能说明
  • 提交事务:将未提交的事务变更持久化到数据库

  • 关键逻辑:

    1. self._execute_command(COMMAND.COM_QUERY, "COMMIT"):发送 COMMIT 命令到数据库

    2. self._read_ok_packet():读取数据库返回的确认包(确保提交成功)

  • 重要性:

    • 若不调用commit(),事务中的变更不会保存到数据库

    • 通常在执行 INSERT/UPDATE/DELETE 后需要调用

使用场景
  • 数据库事务管理:

    try:cursor.execute("BEGIN")  # 开始事务cursor.execute("UPDATE accounts SET balance = balance - 100 WHERE id = 1")cursor.execute("UPDATE accounts SET balance = balance + 100 WHERE id = 2")connection.commit()  # 提交事务
    except:connection.rollback()  # 回滚事务
4. 整体逻辑总结

这三个方法是数据库游标(Cursor)的核心功能,对应 Python 数据库 API 规范(PEP-249)中的标准接口:

  1. execute():执行 SQL 查询,支持参数化查询

  2. fetchone():按顺序获取查询结果的下一行

  3. commit():提交事务,确保数据变更持久化

游标工作流程示例
# 1. 执行查询
cursor.execute("SELECT id, name FROM users WHERE age > 18")
​
# 2. 逐行获取结果
row1 = cursor.fetchone()  # 获取第一行
row2 = cursor.fetchone()  # 获取第二行
​
# 3. 提交事务(若有变更)
connection.commit()
5. 扩展知识:游标与连接的关系
  • 游标(Cursor):

    • 用于执行 SQL 语句和遍历结果集的对象

    • 每个游标独立维护查询状态(如当前行号)

  • 连接(Connection):

    • 与数据库的物理连接,管理事务状态

    • 多个游标可共享同一个连接

  • 最佳实践:

    • 用完游标后及时关闭(cursor.close()

    • 事务完成后及时提交或回滚

    • 避免长时间持有数据库连接

6. 正则表达式基本语法规则

正则表达式是一种用于匹配文本模式的工具,由普通字符和特殊字符(元字符)组成。以下是核心规则:

7. 正常数据正则表达式解析
normal_pattern = r'\[(\d+)\]\s+T:(\d+)\s*C\s+H:(\d+)\s*%\s+L:(\d+)\s*%'
模式分解说明
模式部分解释
r'\[' | 匹配左方括号[r表示原始字符串,避免\转义问题) | | (\d+) | 捕获组1:匹配1个或多个数字(时间戳) | | \]匹配右方括号]
\s+匹配 1 个或多个空白字符(空格、制表符等)
T:匹配文本T:
(\d+)捕获组 2:匹配温度值(整数)
\s*匹配 0 个或多个空白字符
C匹配温度单位C
\s+匹配 1 个或多个空白字符
H:匹配文本H:
(\d+)捕获组 3:匹配湿度值(整数)
\s*%匹配湿度单位%(允许前后有空白)
\s+匹配 1 个或多个空白字符
L:匹配文本L:
(\d+)捕获组 4:匹配光照值(整数)
\s*%匹配光照单位%(允许前后有空白)
匹配示例
  • 输入:[321022] T:25 C H:68% L:0%

  • 匹配结果:

    • 捕获组 1: 321022(时间戳)

    • 捕获组 2: 25(温度)

    • 捕获组 3: 68(湿度)

    • 捕获组 4: 0(光照)

8. 错误数据正则表达式解析
error_pattern = r'\[(\d+)\]\s+DHT11\s+Error!\s+L:(\d+)\s*%'
模式分解说明
模式部分解释
r'\[' | 匹配左方括号[ | | (\d+) | 捕获组1:匹配时间戳 | | \]匹配右方括号]
\s+匹配 1 个或多个空白字符
DHT11匹配文本DHT11
\s+匹配 1 个或多个空白字符
Error!匹配文本Error!
\s+匹配 1 个或多个空白字符
L:匹配文本L:
(\d+)捕获组 2:匹配光照值(整数)
\s*%匹配光照单位%(允许前后有空白)
匹配示例
  • 输入:[405018] DHT11 Error! L:2%

  • 匹配结果:

    • 捕获组 1: 405018(时间戳)

    • 捕获组 2: 2(光照)

9. 正则表达式核心元字符说明
元字符含义
\转义字符,用于匹配特殊字符(如[]\s等)
[]字符集,匹配方括号内的任意字符(如[0-9]匹配数字)
()捕获组,用于提取匹配的子字符串(如(\d+)提取数字)
\d匹配数字(等价于[0-9]
\s匹配空白字符(空格、制表符、换行符等)
+量词:匹配 1 次或多次(如\d+匹配至少 1 个数字)
*量词:匹配 0 次或多次(如\s*匹配 0 个或多个空白)
\A匹配字符串开头
\Z匹配字符串结尾
|或操作(如a|b匹配ab
10. 扩展:正则表达式进阶写法
1. 匹配小数温度(如 25.5°C)
normal_pattern = r'\[(\d+)\]\s+T:(\d+\.\d+|\d+)\s*C\s+H:(\d+)\s*%\s+L:(\d+)\s*%'
  • (\d+\.\d+|\d+):匹配整数或小数(如2525.5

2. 匹配更灵活的空白字符
normal_pattern = r'\[(\d+)\](\s+)T:(\d+)\s*C\s*H:(\d+)\s*%\s*L:(\d+)\s*%'
  • (\s+):明确匹配时间戳后的空白字符

3. 添加行首尾匹配
normal_pattern = r'^\[(\d+)\]\s+T:(\d+)\s*C\s+H:(\d+)\s*%\s+L:(\d+)\s*%$'
  • ^:匹配行开头

  • $:匹配行结尾,确保整行完全匹配

11. 正则表达式测试方法

推荐使用在线工具测试正则表达式,例如:

  • Regex101:可视化匹配过程,显示捕获组结果

  • Pythex:专门用于 Python 正则表达式测试

测试步骤
  1. 输入正则表达式

  2. 输入测试字符串

  3. 查看匹配结果和捕获组内容

  4. 根据结果调整正则表达式

12. 正则表达式最佳实践
  1. 使用原始字符串

    r'\[(\d+)\]'  # 推荐,避免\转义问题
    '\[(\d+)\]'   # 不推荐,需处理\转义
  2. 明确匹配范围

    • 尽量使用^$匹配行首尾,避免部分匹配

    • 示例:^Pattern$Pattern 更精确

  3. 分组清晰

    • 按逻辑分组,便于后续提取数据

    • 不需要提取的分组使用非捕获组:(?:pattern)

  4. 逐步构建

    • 先编写简单模式,再逐步添加复杂条件

    • 例如:先匹配时间戳\[\d+\],再添加温度部分T:\d+C

通过理解这些规则,可以根据实际数据格式灵活调整正则表达式,确保准确匹配和数据提取。如果需要匹配更复杂的格式,可逐步扩展模式并通过测试验证匹配效果。

13. 函数 match(pattern, string, flags=0) 解析

这个函数是 Python 中 re 模块的 match() 函数实现,用于从字符串开头尝试匹配正则表达式模式。以下是对其功能、参数和实现逻辑的详细解析:

一、函数功能概述
def match(pattern, string, flags=0):"""Try to apply the pattern at the start of the string, returninga Match object, or None if no match was found."""return _compile(pattern, flags).match(string)
  • 核心功能:从字符串的开头开始尝试匹配正则表达式模式

  • 返回值:

    • 匹配成功:返回 Match 对象(包含匹配结果和分组信息)

    • 匹配失败:返回 None

  • 关键调用:

    1. _compile(pattern, flags):编译正则表达式模式

    2. match(string):在字符串上执行匹配操作

二、参数详解
参数类型说明
patternstr正则表达式模式字符串(如 r'\d+' 匹配数字)
stringstr要匹配的目标字符串(如 "123abc"
flagsint匹配标志(可选,默认 0),用于修改匹配行为,例如:
- re.I:忽略大小写 - re.M:多行匹配 - re.S:点号匹配所有字符
三、实现逻辑解析
  1. 正则表达式编译

    _compile(pattern, flags)
    • 将字符串形式的正则表达式pattern编译为内部可执行的模式对象

    • 编译后可提高匹配效率(避免重复编译相同模式)

  2. 字符串匹配

    .match(string)
    • string执行匹配操作,仅从字符串开头开始匹配

    • 若开头不匹配模式,则直接返回None,不继续向后匹配

  3. 示例说明

    import re
    ​
    # 匹配成功
    result = re.match(r'\d+', '123abc')
    print(result.group())  # 输出: '123'
    ​
    # 匹配失败(开头不是数字)
    result = re.match(r'\d+', 'abc123')
    print(result)  # 输出: None
四、与其他匹配函数的对比
函数匹配位置示例(模式\d+,字符串'abc123'
re.match()字符串开头匹配失败(返回None
re.search()字符串任意位置匹配成功(返回'123'
re.findall()查找所有匹配返回['123']
五、flags 参数常用取值
re.match(r'abc', 'ABC', re.I).group()  # 输出: 'ABC'
  1. 多行匹配(re.M

    pattern = r'^Hello'
    string = """Hello World
    Hello Python"""
    ​
    # 不使用re.M时仅匹配第一行
    re.match(pattern, string).group()  # 输出: 'Hello'
    ​
    # 使用re.M时匹配所有行开头
    re.match(pattern, string, re.M)    # 仍只匹配第一行(match()仅从开头匹配)
    re.findall(pattern, string, re.M)  # 输出: ['Hello', 'Hello']
  2. 点号匹配所有字符(re.S

    pattern = r'Hello.*World'
    string = "Hello\nWorld"
    ​
    re.match(pattern, string).group()  # 匹配失败(.不匹配\n)
    re.match(pattern, string, re.S).group()  # 匹配成功(.匹配\n)
六、Match 对象常用方法和属性
方法 / 属性说明
group(n)获取第 n 个捕获组的匹配结果(n=0为整个匹配结果)
groups()以元组形式返回所有捕获组的结果
groupdict()以字典形式返回命名捕获组的结果
start(n)获取第 n 个捕获组的起始位置
end(n)获取第 n 个捕获组的结束位置
span(n)获取第 n 个捕获组的起始和结束位置(返回元组(start, end)
七、使用场景建议
  1. 明确需要从开头匹配时

    • 验证字符串格式(如 IP 地址、邮箱等)

    • 示例:验证手机号(开头为 13/14/15/18 等)

      def is_valid_phone(phone):return re.match(r'^1[3-9]\d{9}$', phone) is not None
  2. 与其他匹配函数配合使用

    • 先使用match()尝试开头匹配,失败后再用search()全局搜索

    def find_pattern(pattern, string):result = re.match(pattern, string)if not result:result = re.search(pattern, string)return result
  3. 结合 flags 参数处理复杂场景

    • 处理包含特殊字符或需要多行匹配的文本

八、注意事项
  1. 仅开头匹配限制

    • match()不会搜索字符串中间的匹配项,若需要全局匹配请使用re.search()

  2. 编译后的模式对象

    • 对于频繁使用的正则表达式,建议提前编译以提高效率:

      pattern = re.compile(r'\d+')
      result = pattern.match('123abc')
  3. 转义字符处理

    • 使用原始字符串(

      r''

      )避免转义问题:

      re.match(r'\\d+', '\\d123')  # 匹配'\\d'
      re.match('\\\\d+', '\\d123') # 等价于上面的原始字符串

通过理解match()函数的工作原理和参数用法,可以更精准地控制正则表达式的匹配行为,尤其是在需要从字符串开头进行模式匹配的场景中。

相关文章:

  • 【EDA软件】【联合Modelsim 同步FIFO仿真】
  • GitHub 趋势日报(2025年06月27日)
  • 雷卯针对灵眸科技EASY EAI nano RV1126 开发板防雷防静电方案
  • 复杂驱动开发-TLE9471的休眠流程与定时唤醒
  • DMA之 Trigger input和 Trigger Output 概念
  • 具身智能系列教程——(一)具身智能研究与发展
  • 户外人像要怎么拍 ?
  • 【Docker基础】Docker容器管理:docker top及其参数详解
  • electron中显示echarts
  • 【NLP】自然语言项目设计03
  • 关于ubuntu 20.04系统安装分区和重复登录无法加载桌面的问题解决
  • 【数据标注】事件标注1
  • Vue工程化实现约定式路由自动注册
  • Go开发工程师-Golang基础知识篇
  • 数据结构:最小生成树—Prim(普里姆)与Kruskal(克鲁斯卡尔)算法
  • 什么是哈希链(Hash Chain)?
  • Redis 实现分布式锁
  • 分布式集群压测
  • 第8章-财务数据
  • VR训练美国服务器:高性能解决方案与优化指南