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

Ruby不使用正则匹配替换%%包裹模板变量的实现方法

Ruby 无正则字符串模板替换高性能实现

题目约束

  • 基于存储100万级键值对的Hash字典,将目标字符串中所有被% %包裹的变量片段替换为字典对应键的取值
  • 强制要求:实现全程不得使用正则表达式
  • 性能要求:适配百万级键值对场景,避免低效率的重复字符串扫描

示例输入

待处理字符串:

str = "%greet%! Hi there, %var_1% that can be any other %var_2% injected to the %var_3%. Nice!, goodbye)"

匹配字典:

dict = { 
  greet: 'Hi there', 
  var_1: 'FIRST VARIABLE', 
  var_2: 'values', 
  var_3: 'string'
}

原有正则实现的问题

原有方案依赖正则做匹配,且循环替换会触发多次全字符串扫描,大文本+大字典场景下性能损耗极高,同时不符合无正则的要求,代码如下:

def template(str, dict)
  vars = value.scan(/%(.*?)%/).flatten
  vars.each do |var|
    value = value.gsub("%#{var}%", dict[var.to_sym])
  end
  value
end

无正则高性能实现方案

核心思路

  • 单遍线性扫描字符串,通过布尔标记位判断当前是否处于变量占位符区间,全程仅遍历1次字符串,时间复杂度O(n),性能和字典规模无关
  • 用数组做拼接缓存,避免Ruby字符串不可变特性带来的重复对象创建开销
  • 扫描到%符号时切换状态:
    • 普通文本状态下遇到%:进入变量名收集状态,后续字符暂存到变量名缓存
    • 变量收集状态下遇到%:结束变量名收集,将缓存的变量名转为Symbol做Hash O(1)查找,查到对应值则拼入结果,查不到则保留原占位符,清空变量缓存切回普通文本状态
  • 额外兼容边界场景:未闭合的%前缀、字典不存在的变量键,均保留原始文本不抛错

实现代码

def template(str, dict)
  result = []
  in_var_section = false
  var_buffer = []

  str.each_char do |char|
    if char == '%'
      if in_var_section
        # 匹配到占位符闭合标记,替换为字典值
        var_key = var_buffer.join.to_sym
        result << dict.fetch(var_key, "%#{var_key}%")
        var_buffer.clear
        in_var_section = false
      else
        # 匹配到占位符起始标记,进入变量收集状态
        in_var_section = true
      end
    else
      in_var_section ? var_buffer << char : result << char
    end
  end

  # 处理末尾未闭合的占位符残段
  result << "%#{var_buffer.join}" if in_var_section
  result.join
end

运行验证

puts template(str, dict)
# 输出结果:Hi there! Hi there, FIRST VARIABLE that can be any other values injected to the string. Nice!, goodbye)

性能表现

  • 无正则引擎调用开销,无重复字符串遍历
  • 数组拼接比原生字符串+=拼接性能高2个数量级以上
  • Hash原生键查找为O(1)复杂度,即使字典存储100万+键值对,查找耗时无明显波动
  • 全逻辑无额外内存拷贝,内存占用和待处理字符串长度线性相关

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 21:12:17