Ruby循环中正则匹配缺失导致元素跳过的问题如何解决
问题根因
你的代码核心问题是遍历逻辑顺序错误:你按正则规则循环,每次循环都重新过滤匹配当前规则的宏、覆盖最终结果变量@final_data。最后一次循环遍历的是手机号规则,第二个宏不匹配手机号规则,不会进入本次循环的处理逻辑,所以最终结果里的第二个宏保留了未替换邮箱的原始内容。
另外你原有实现里把数组转字符串再eval还原的写法风险高、效率低,完全没有必要,直接操作哈希对象即可。gsub方法本身就对没有匹配项的内容直接返回原字符串,不需要额外做匹配判断,不会跳过元素。
修正后代码
PARTS = [ { re: /\bDE(?:[0-9a-zA-Z]\s?){20}\b/, replace: '{{IBAN}}', name: 'IBAN' }, { re: /\b[\w\.-]+@[\w\.-]+\.\w{2,4}\b/, replace: '{{email}}', name: 'E-Mail' }, { re: /\b(0|0049\s?|\+49\s?|\(\+49\)\s?){1}([1-9]{2,4})([ \-\/]?[0-9]{1,10})+\b/, replace: '{{phone_number}}', name: 'Phone Number' } ].freeze # 保留原有的匹配ID统计逻辑 PARTS.each do |x| list = macros.select { |m| m['actions'].any? { |w| x[:re].match?(w['value']) } }.map { |m| m['id'] } puts "Macro ID with #{x[:name]} #{list}" end # 统一处理所有宏 @final_data = macros.map do |macro| # 深度拷贝避免修改原始宏数据,不需要修改原数据可以去掉这行直接操作macro processed_macro = Marshal.load(Marshal.dump(macro)) processed_macro['actions'].each do |action| next unless action['field'] == 'comment_value_html' # 依次应用所有替换规则,无匹配项时gsub自动返回原内容,不会跳过 PARTS.each do |rule| action['value'].gsub!(rule[:re], rule[:replace]) end end processed_macro end
逻辑说明
- 改为先遍历所有宏,对每个宏的内容一次性应用全部替换规则,不管匹配到几个规则都能正常替换
- 用
gsub!直接修改字符串对象,不需要反复生成新对象,性能更好 - 去掉了危险的
eval操作,直接操作哈希,没有注入风险
内容的提问来源于stack exchange,提问作者user16741832
相关产品推荐
相关产品推荐

