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

如何将整数列表转换为精准匹配的动态Ruby正则表达式?

问题:Ruby中基于整数列表生成紧凑正则表达式

我想在Ruby里根据整数列表动态生成紧凑的正则表达式。比如输入列表:
[1,2,3,4,5,6,7,9,10,11,12,13,14,15,17,18,19,20,21,22,23,25,26,27,28,29,30,31]
期望生成的正则是:
/^([1-7]|9|1[0-5]|1[7-9]|2[0-3]|2[5-9]|3[0-1])$/

核心需求是把连续数字范围合并成紧凑格式:比如1-7转为[1-7]、10-15转为1[0-5],但我写的代码只会输出冗长的枚举形式,求修改优化方案,要满足:

  • 合并连续范围为[start-end]格式
  • 妥善处理多位数的公共前缀(比如十位相同的连续数)
  • 代码可读且高效

解决方案

核心分两步:先把整数列表分组为连续区间,再将每个区间转换成紧凑的正则片段,最后拼接成完整正则。

1. 分组连续整数区间

先实现一个方法,把输入的整数列表(自动去重排序)分割成连续的数字块,每个块用起始和结束值表示:

def group_consecutive_numbers(numbers)
  return [] if numbers.empty?
  sorted_numbers = numbers.uniq.sort
  groups = [[sorted_numbers.first]]
  
  sorted_numbers[1..].each do |num|
    last_group = groups.last
    if num == last_group.last + 1
      last_group << num
    else
      groups << [num]
    end
  end
  
  groups.map { |g| [g.first, g.last] }
end

2. 将区间转为紧凑正则片段

针对每个[start, end]区间,生成对应的正则字符串,重点处理同位数数字的公共前缀:

def range_to_regex_part(start_num, end_num)
  return start_num.to_s if start_num == end_num
  
  start_str = start_num.to_s
  end_str = end_num.to_s
  
  # 处理位数相同的连续数,提取公共前缀
  if start_str.length == end_str.length
    prefix = ""
    (0...start_str.length).each do |i|
      if start_str[i] == end_str[i]
        prefix += start_str[i]
      else
        suffix_start = start_str[i..]
        suffix_end = end_str[i..]
        return "#{prefix}[#{suffix_start}-#{suffix_end}]"
      end
    end
  end
  
  # 位数不同的连续数(比如9-10)直接用范围格式
  "#{start_num}-#{end_num}"
end

3. 拼接成完整正则

把所有片段用|连接,加上边界匹配符生成最终正则:

def generate_compact_regex(numbers)
  return nil if numbers.empty?
  
  groups = group_consecutive_numbers(numbers)
  regex_parts = groups.map { |start, end_| range_to_regex_part(start, end_) }
  regex_str = "^(#{regex_parts.join('|')})$"
  
  Regexp.new(regex_str)
end

测试验证

用你提供的输入列表测试:

numbers = [1,2,3,4,5,6,7,9,10,11,12,13,14,15,17,18,19,20,21,22,23,25,26,27,28,29,30,31]
puts generate_compact_regex(numbers).inspect

输出结果完全符合预期:
/^([1-7]|9|1[0-5]|1[7-9]|2[0-3]|2[5-9]|3[0-1])$/

代码说明

  • group_consecutive_numbers自动处理无序、重复的输入,确保分组逻辑准确
  • range_to_regex_part优先提取多位数的公共前缀,只对差异部分做范围匹配,生成最紧凑的正则片段
  • 最终正则加上^和$,确保匹配整个字符串,避免部分匹配的问题

内容的提问来源于stack exchange,提问作者Hussain Abbas Bani Wala

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 06:37:12