如何用regular expressions从指定格式记录中提取三类值?
解决方法:精准正则匹配提取三类值
别担心,正则看起来复杂但只要抓准你的格式规律就很容易搞定!你的每条记录格式是**[多词字符串] [整数] x [浮点数] mm**,核心是要把这三个部分精准分隔开,避免把无关字符混进去。
正则表达式设计思路
先拆解你的格式规则:
- 第一部分:多词字符串(不含数字,因为整数是第一个出现的数字),直到第一个数字前的内容
- 第二部分:纯整数,后面跟着
x(前后可能有空格) - 第三部分:浮点数(带小数点),最后是
mm(前后可能有空格)
基于这个规则,我们可以写出针对性的正则:
^([^\d]+?)\s+(\d+)\s*x\s*(\d+\.\d+)\s*mm$
正则各部分解释
^:匹配字符串开头,确保从第一条内容开始匹配([^\d]+?):非贪婪捕获除数字外的所有字符(对应多词字符串),非贪婪模式(+?)避免把后面的空格也包含进去\s+:匹配一个或多个空格,分隔字符串和整数(\d+):捕获整数部分(一个或多个数字)\s*x\s*:匹配x,允许前后有任意数量的空格(包括0个,兼容3x2.0或3 x 2.0的情况)(\d+\.\d+):捕获浮点数部分(必须带小数点,比如2.0)\s*mm$:匹配结尾的mm,允许前后有空格,$确保匹配到字符串结尾
代码示例(以Python为例)
下面是完整的提取代码,包含匹配、提取和整理成表格的逻辑:
import re # 定义正则模式 pattern = r'^([^\d]+?)\s+(\d+)\s*x\s*(\d+\.\d+)\s*mm$' # 你的1000条记录列表(这里用示例数据) records = [ "Round 3 x 2.0 mm", "Star 12 x 45.0 mm", "Oval CAB 5 x 6.0 mm", "Square-Round 4 x 3.5 mm" # 测试含特殊字符的字符串 ] # 提取结果存入列表,方便后续生成表格 extracted_data = [] for idx, record in enumerate(records, 1): match = re.match(pattern, record) if match: # 提取并整理各部分:去除字符串前后空格,转换数据类型 item = { "序号": idx, "字符串": match.group(1).strip(), "整数": int(match.group(2)), "浮点数": float(match.group(3)) } extracted_data.append(item) else: print(f"⚠️ 第{idx}条记录格式异常,无法匹配:{record}") # 打印提取后的表格(也可以用pandas导出为Excel/CSV) print("提取结果表格:") print(f"{'序号':<4} {'字符串':<15} {'整数':<5} {'浮点数':<6}") print("-" * 35) for data in extracted_data: print(f"{data['序号']:<4} {data['字符串']:<15} {data['整数']:<5} {data['浮点数']:<6}")
扩展兼容情况
如果你的浮点数可能不带小数点(比如5 mm而不是5.0 mm),可以把正则里的浮点数部分改成(\d+(?:\.\d+)?),这样既可以匹配5也可以匹配5.0:
^([^\d]+?)\s+(\d+)\s*x\s*(\d+(?:\.\d+)?)\s*mm$
为什么之前的尝试出错?
你提到之前得到Round3x、3x20mm这类混乱结果,大概率是因为:
- 没有用分组捕获,导致把多个部分的内容混在一起
- 用了贪婪匹配(比如
+而不是+?),把后面的数字或符号也包含进了字符串部分 - 没有处理空格的不确定性,比如
x前后的空格没匹配到
按照上面的方法,就能精准把三个部分分开啦!
内容的提问来源于stack exchange,提问作者Mikael Diak
相关产品推荐
相关产品推荐

