Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何扩展范围\w\d+-\w\d+;_Java - Fatal编程技术网

Java 如何扩展范围\w\d+-\w\d+;

Java 如何扩展范围\w\d+-\w\d+;,java,Java,我有一些字符串类型的数据,比如“U39、R11、U50-U55、U99” 如何通过扩展连字符范围将其更改为“U39、R11、U50、U51、U52、U53、U54、U55、U99 我尝试使用Java正则表达式来掌握“-”之前和“-”之后的数字和字母前缀,然后使用循环从头到尾打印数字。有更好的解决方案吗?当然,有多种方法可以做到这一点。我认为使用正则表达式是一种非常简单的方法。类似这样的列表中的项目流是Java 8流(而不是传统迭代)的一个非常好的用例: 打印出U23、R45、U12、U13、U1

我有一些字符串类型的数据,比如“
U39、R11、U50-U55、U99

如何通过扩展连字符范围将其更改为“
U39、R11、U50、U51、U52、U53、U54、U55、U99


我尝试使用Java正则表达式来掌握“-”之前和“-”之后的数字和字母前缀,然后使用循环从头到尾打印数字。有更好的解决方案吗?

当然,有多种方法可以做到这一点。我认为使用正则表达式是一种非常简单的方法。类似这样的列表中的项目流是Java 8流(而不是传统迭代)的一个非常好的用例:


打印出
U23、R45、U12、U13、U14、U15、R7

我认为一个合理的方法是这样进行:

  • 使用将字符串拆分为字符串数组(称之为
    labelsIn
  • 创建一个
    ArrayList
    (称之为
    labelsOut
    )来保存结果
  • 标签上循环
    数组和每个元素:
    • 如果它
      [A-Z][0-9]+
      ,则将其附加到
      标签输出
      列表中
    • 否则,如果它匹配模式
      ([A-Z])([0-9]+)-\1([0-9]+)
      (调用对象
      match
      ),则提取数字
      low
      high
      (使用
      Integer.valueOf(match.group(2))
      Integer.valueOf(match.group(3))
      )对于从
      low
      high
      的所有编号
      n
      ,添加到
      labelsOut
      列表中
    • 否则就是语法错误
  • 从带有
    ,“
    标签的
    列表中
  • 如果您认为合适,可以在
    “、”
    “-”
    周围允许零个或多个空格字符(
    \s*
    ),从而稍微概括正则表达式


    请注意,上述程序是为教学清晰而优化的,而不是为了表现。如果需要,可以去掉一些中间结果。你也可以考虑使用java 8来简化代码。< /P >如果你有<代码> X50-A11<代码>,那标题是不是我所没有的双关语?我认为将其改为“如何扩展标签范围?”@5gon12eder“pun”:LOL-如果我从我的第一语言逐字翻译,我可能会想到“粘合笔划”。一个法国人可能会制作“联盟线”。@laune我想这可能是一个军事参考,其中的符号标记了各种战舰或“前锋前线”中的任何东西。也许他们用这种语法来描述他们的策略?@5gon12eder还不错,但美国海军船体编号包含连字符(DD-69)。谢谢你的回复。我从来没有见过这样使用溪流的方法。它确实好得多@宝成利太好了我很高兴你发现它很有用。一旦你习惯了,流是非常强大和直观的。@BaochengLi如果你能接受对你有用的答案,我将不胜感激。很抱歉,响应太晚,行IntStream.rangeClosed(from,to).map(I->matcher.group(0)+I).forEach(expandedList::add);它在eclipse中有语法错误。另一个问题,输入字符串的初始值是否需要展开?谢谢!我不确定String.format(“%s%d”,match.group(1),n)的含义,输出是什么?
    match.group(1)
    返回匹配的字符(正则表达式中第一对括号内的内容),例如
    “U”
    String.format
    %s
    替换为作为参数1传递的字符串,将
    %d
    替换为作为参数2传递的整数表示形式。因此,如果
    n=51
    ,格式化的字符串将读取
    “U51”
    。请尝试查看。很抱歉响应太晚,我是否需要按照您所说的从低到高循环所有数字n。当然,如果您希望它们出现在列表中,如您在示例中使用
    low=50
    high=55
    所示。您将得到类似于for(int n=low;n)的
    
    
    class Expander {
        private final List<String> expandedList = new ArrayList<>();
        private final Pattern PATTERN = Pattern.compile("([UR])(\\d+)-[UR](\\d+)");
    
        public static String expand(String input) {
            return Arrays.stream(input.split(",")).parallel()
                .collect(Expander::new, Expander::accept, Expander::combine)
                .expandedList.stream().collect(Collectors.joining(","));
        }
    
        private void accept(String item) {
            Matcher matcher = PATTERN.matcher(item);
            if (matcher.matches()) {
                int from = Integer.parseInt(matcher.group(2));
                int to = Integer.parseInt(matcher.group(3));
                IntStream.rangeClosed(from, to)
                    .mapToObj(i -> matcher.group(1) + i)
                    .forEach(expandedList::add);
            } else {
                expandedList.add(item);
            }
        }
    
        private Expander combine(Expander other) {
            expandedList.addAll(other);
            return this;
        }
    }
    
    public static void main(String[] args) {
        System.out.println(Expander.expand("U23,R45,U12-U15,R7");
    }