「简记往来」开发历程系列:正则表达式从入门到实战——批量记礼的完整代码

一、正则基础语法(5分钟入门)

正则表达式用于匹配文本中的特定模式。批量记礼中,它用来从"张叔叔 800"这样的文本中提取出姓名和金额。

常用元字符

元字符 含义 示例
\d 数字 \d+ 匹配一个或多个数字
\s 空白字符 \s+ 匹配一个或多个空格
\w 字母/数字/下划线 \w+ 匹配单词
^ 字符串开头 ^张 匹配以"张"开头的行
$ 字符串结尾 800$ 匹配以"800"结尾的行
[] 字符集 [姓名] 匹配"姓"或"名"
() 捕获组 (张叔叔) 捕获"张叔叔"

二、简记往来的完整正则代码

批量记礼的核心解析函数:

javascript 复制代码
function tryParse(line) {
    // 移除首尾空格
    line = line.trim()
    if (!line) return null
    
    // 尝试1:标准"姓名 金额"
    // 匹配:中文/英文姓名 + 空格 + 数字(含小数)
    let match = line.match(/^([\u4e00-\u9fa5a-zA-Z·]+)\s+([\d.]+)/)
    if (match) {
        return { 
            name: match[1].trim(), 
            amount: parseFloat(match[2]) 
        }
    }
    
    // 尝试2:无空格"姓名金额"
    // 匹配:中文/英文姓名 + 数字(无空格)
    match = line.match(/^([\u4e00-\u9fa5a-zA-Z·]+)([\d.]+)/)
    if (match) {
        return { 
            name: match[1].trim(), 
            amount: parseFloat(match[2]) 
        }
    }
    
    // 尝试3:金额在末尾"任意内容 金额"
    // 匹配:任意内容 + 末尾的数字
    match = line.match(/([\d.]+)$/)
    if (match) {
        const namePart = line.replace(/([\d.]+)$/, '').trim()
        if (namePart.length > 0) {
            return { 
                name: namePart, 
                amount: parseFloat(match[1]) 
            }
        }
    }
    
    return null
}

三、5个常见踩坑点

踩坑1:中英文混排

如果姓名包含英文(如"John 500"),[\u4e00-\u9fa5] 匹配不到英文字母。解决方案:加上 a-zA-Z

踩坑2:中间点(少数民族姓名)

"阿不都·热合曼"中间的 · 需要用 · 匹配。解决方案:加上 ·

踩坑3:金额带千分位

"1,000" 这种格式,用 [\d.] 匹配不到逗号。解决方案:先替换逗号再解析。

踩坑4:换行符不一致

Windows用 \r\n,Linux/Mac用 \n。解决方案:统一用 \n 拆分,再清理 \r

踩坑5:空行和多余空格

用户可能输入空行,或者行首行尾有多余空格。解决方案:先 trim() 再判断是否为空。

四、测试工具推荐

  • regex101.com:在线正则测试,支持多种语言
  • Chrome控制台'张叔叔 800'.match(/^([\u4e00-\u9fa5]+)\s+(\d+)/)
  • Node.js REPL:本地快速测试

五、总结

正则表达式不难,关键是多测试、多迭代

简记往来的批量记礼功能,从第一版到第五版,就是不断发现新问题、不断改进的过程。如果你也在做文本解析,建议先在regex101上测试通过,再放到代码里。