Regex 从已排序的数字列表生成正则表达式数字范围

Regex 从已排序的数字列表生成正则表达式数字范围,regex,algorithm,range,digit,Regex,Algorithm,Range,Digit,假设我有一些已排序的整数列表,我想将它们转换为各自的正则表达式数字范围,如下所示: [0,1,2,3,4,5,6,7,8,9]=>[0-9] [0,1,2,3,4,6,7,8,9]=>[0-46-9] [0,1,3,4,5,8,9]=>[013-589] [0,2,4,6,8]=>[02468] 我不想让正则表达式匹配这里的任何东西。我试图从一组数字生成一个正则表达式范围 我真的只是想看看是否已经有一些事实上的算法来做这样的事情 编辑:基于@Jerry_Coffin的答案,一种基于Java的算法

假设我有一些已排序的整数列表,我想将它们转换为各自的正则表达式数字范围,如下所示:

  • [0,1,2,3,4,5,6,7,8,9]=>[0-9]
  • [0,1,2,3,4,6,7,8,9]=>[0-46-9]
  • [0,1,3,4,5,8,9]=>[013-589]
  • [0,2,4,6,8]=>[02468]
  • 我不想让正则表达式匹配这里的任何东西。我试图从一组数字生成一个正则表达式范围

    我真的只是想看看是否已经有一些事实上的算法来做这样的事情

    编辑:基于@Jerry_Coffin的答案,一种基于Java的算法:

    List<Integer> digits = Arrays.asList(0, 1, 3, 4, 5, 8, 9);
    StringBuilder digitRange = new StringBuilder().append('[');
    int consecutive = 0;
    for (int i = 0; i < digits.size(); i++) {
      if (i == digits.size() - 1 || digits.get(i) + 1 != digits.get(i + 1)) {
        if (consecutive > 1) {
            digitRange.append('-');
        }
        digitRange.append(digits.get(i));
        consecutive = 0;
      } else {
        if (consecutive == 0) {
          digitRange.append(digits.get(i));
        }
        consecutive++;
      }
    }
    digitRange.append(']');
    System.out.println(digitRange.toString());
    
    List digits=Arrays.asList(0,1,3,4,5,8,9);
    StringBuilder digitRange=new StringBuilder().append(“[”);
    int=0;
    对于(int i=0;i1){
    digirange.append('-');
    }
    digirange.append(digits.get(i));
    连续=0;
    }否则{
    如果(连续==0){
    digirange.append(digits.get(i));
    }
    连续++;
    }
    }
    追加(']');
    System.out.println(digitRange.toString());
    
    输出:
    [013-589]


    您可以随意查找改进或问题。

    您可能是从排序输入开始的(如果不是,您几乎肯定希望从排序输入开始)

    从这里开始,从第一个(未处理的)项目开始,写出它。只要这些数字是连续的,就遍历它们。假设你有两个以上的连续数字,写出一个破折号,然后写出最后一个连续数字。如果有两个或更少的连续数据,只需按原样将它们写入输出即可


    重复,直到输入结束。

    我可以提出不同的方法

    在识别间隔的列表中迭代。我们保留两个变量
    left
    right
    (区间界限),每次有两个not连续值时,我们将区间写入
    StringBuilder

    int[] list = new[] { 0, 1, 3, 4, 5, 8, 9 };
    int left = 0;
    int right = 0;
    for (int i = 0; i < list.Length; i++)
    {
        if (i == 0) // first case
        {
            left = right = list[i];
            continue;
        }
        if (list[i] - list[i - 1] > 1) // not consecutive
        {
            builder.AppendFormat(Write(left, right));
            left = list[i];
        }
        right = list[i];
    }
    builder.AppendFormat(Write(left, right));// last case
    builder.Append("]");
    

    这些列表已经排序了吗?是的,它们已经排序了。将更新问题以澄清这一点。根据第3条——“假设你连续两次以上”。
    private static string Write(int left, int right)
    {
        return
            left == right
                ? left.ToString()
            : right - left == 1
                ? string.Format("{0}{1}", left, right)
                : string.Format("{0}-{1}", left, right);
    }