You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python正则表达式高效解析SVG路径元素的d属性命令

我之前做SVG路径解析的时候正好踩过类似的坑,你的思路没问题,核心就是要先正确拆分所有合法的命令和数值,再把它们按命令分组。之前的问题出在数值匹配的正则不对,导致连写的小数(比如.55.45)被当成了一个整体。

解决方案步骤

1. 先正确拆分所有Token(命令+单个数值)

首先要写一个能精准匹配SVG合法数值的正则,同时匹配所有SVG路径命令字母。合法数值的规则是:

  • 可选负号开头
  • 可以是整数(如123、-4)
  • 可以是小数(如.55、1.67、-.89)

对应的正则表达式是:

token_pattern = r'[mMzZlLhHvVcCsSqQrRtTaA]|-?\d*\.?\d+'

这个正则会把每个命令字母和每个单独的数值都拆分成独立的token,完美解决.55.45这类连写数值的拆分问题。

2. 将Token按命令分组

拆分出所有token后,我们只需要遍历这些token,把每个命令和它后面跟随的所有数值打包成元组,直到遇到下一个命令为止。

完整代码示例

import re

def parse_svg_d(d):
    # 匹配SVG路径命令和合法数值
    token_pattern = r'[mMzZlLhHvVcCsSqQrRtTaA]|-?\d*\.?\d+'
    tokens = re.findall(token_pattern, d)
    
    if not tokens:
        return []
    
    parsed_commands = []
    current_command = tokens[0]
    current_values = []
    
    for token in tokens[1:]:
        # 判断当前token是命令还是数值
        if re.fullmatch(r'[mMzZlLhHvVcCsSqQrRtTaA]', token):
            # 遇到新命令,把之前的命令+数值存入结果
            parsed_commands.append((current_command, *current_values))
            current_command = token
            current_values = []
        else:
            # 是数值,加入当前命令的数值列表
            current_values.append(token)
    
    # 处理最后一组命令
    parsed_commands.append((current_command, *current_values))
    return parsed_commands

# 测试你的示例d属性
d = 'M20 3H4c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h16'
result = parse_svg_d(d)
print(result)

输出结果

[('M', '20', '3'), ('H', '4'), ('c', '-.55', '0', '-1', '.45', '-1', '1'), ('v', '6'), ('c', '0', '.55', '.45', '1', '1', '1'), ('h', '16')]

为什么这个方法可行?

  • 数值正则-?\d*\.?\d+确保了每个合法的数值都会被单独匹配,不会把连写的小数当成一个整体;
  • 遍历分组的逻辑简单清晰,还能自动处理Z/z这类不带数值的命令(会生成('Z',)这样的元组),兼容性很好。

如果你想尝试用单个正则直接匹配命令+数值组,理论上可以,但需要针对每个命令的数值数量写复杂的分支规则,维护起来非常麻烦,不如这种拆分+分组的方式直观可靠。

内容的提问来源于stack exchange,提问作者MisterNox

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 16:02:54