4. 解析G和M指令
任务目标
实现一个G代码解析器的核心函数,能够从一行G代码文本中正确提取G指令(如G0、G90)和M指令(如M3、M5),并返回结构化结果。解析需支持行号前缀(N10)、注释剥离、大小写不敏感,以及同一行内多条指令的提取。
实现方案
使用正则表达式匹配G/M后跟1~3位数字的模式,遍历所有匹配项。解析前先剥离分号后的注释,并统一转为大写。返回结果包含指令类型(G/M)、指令数字和原始匹配文本。
完整代码
import re
def parse_gcode_line(line: str) -> list[dict]:
"""
解析单行G代码,提取所有G和M指令。
返回示例: [{'type': 'G', 'code': 0, 'raw': 'G0'}, ...]
"""
# 剥离分号注释并转为大写
code_part = line.split(';')[0].strip().upper()
if not code_part:
return []
# 匹配 G/M + 1~3位数字(不匹配G代码中可能出现的字母后缀如G0.1)
pattern = r'\b([GM])(\d{1,3})\b'
matches = re.findall(pattern, code_part)
result = []
for type_letter, num_str in matches:
result.append({
'type': type_letter,
'code': int(num_str),
'raw': f'{type_letter}{num_str}'
})
return result
# 最小验证入口
if __name__ == '__main__':
test_lines = [
"N10 G90 G0 X10 Y20 ; 快速定位",
"g1 x5 y5",
"M3 S1000",
"N20 G91 G1 X-5 F100 M8",
"G0X0Y0", # 无空格边界
"; 纯注释行",
""
]
for line in test_lines:
print(f"输入: {line!r}")
print(f"输出: {parse_gcode_line(line)}\n")
运行与验证
运行方式:将代码保存为 gcode_parser.py,在终端执行 python gcode_parser.py。
预期输出(与代码逻辑严格对应):
输入: 'N10 G90 G0 X10 Y20 ; 快速定位'
输出: [{'type': 'G', 'code': 90, 'raw': 'G90'}, {'type': 'G', 'code': 0, 'raw': 'G0'}]
输入: 'g1 x5 y5'
输出: [{'type': 'G', 'code': 1, 'raw': 'G1'}]
输入: 'M3 S1000'
输出: [{'type': 'M', 'code': 3, 'raw': 'M3'}]
输入: 'N20 G91 G1 X-5 F100 M8'
输出: [{'type': 'G', 'code': 91, 'raw': 'G91'}, {'type': 'G', 'code': 1, 'raw': 'G1'}, {'type': 'M', 'code': 8, 'raw': 'M8'}]
输入: 'G0X0Y0'
输出: [{'type': 'G', 'code': 0, 'raw': 'G0'}]
输入: '; 纯注释行'
输出: []
输入: ''
输出: []
验证判定标准:运行后观察输出是否与上述预期一致。重点确认:①注释内容被正确剥离;②小写g/m被转为大写识别;③同一行多条指令全部提取;④无空格粘连写法(如G0X0)仍能正确匹配;⑤纯注释行和空行返回空列表。
边界说明
本解析器针对整数G/M指令设计,不处理带小数点的G代码(如G0.1)或带字母后缀的扩展指令(如G54.1)。如需支持这些格式,需扩展正则表达式,但不影响当前案例对基础G/M指令解析目标的完整覆盖。