我有一些像“U39,R11,U50-U55,U99
”这样的字符串类型数据。
如何通过扩展连字范围将其更改为“U39,R11,U50,U51,U52,U53,U54,U55,U99
”?
我尝试使用Java正则表达式来掌握“ - ”之前和“ - ”之后的数字和字母前缀,然后使用循环从头到尾打印数字。有更好的解决方案吗?
答案 0 :(得分:0)
当然,有各种方法可以做到这一点。我认为使用正则表达式是一种非常简单的方法。像这样的列表中的项目流是Java 8流的一个很好的用例(而不是传统的迭代):
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");
}
打印出U23,R45,U12,U13,U14,U15,R7
答案 1 :(得分:0)
我认为一种合理的方式就是这样:
String.split(",")
将字符串拆分为字符串数组(称之为labelsIn
)。ArrayList<String>
(称之为labelsOut
)以保存结果。labelsIn
数组并为每个元素循环:
[A-Z][0-9]+
,请将其附加到labelsOut
列表。([A-Z])([0-9]+)-\1([0-9]+)
匹配(调用Matcher
对象match
),请提取数字low
和high
(使用{{1对于Integer.valueOf(match.group(2))
到Integer.valueOf(match.group(3))
的所有数字n
,请将String.format("%s%d", match.group(1), n)
添加到low
列表。high
列表labelsOut
。如果您认为合适,可以在labelsOut
和","
周围允许零个或多个空白字符(\s*
)来概括正则表达式。
请注意,上述过程针对说明清晰度而非性能进行了优化。如果需要,您可以删除一些中间结果。您也可以考虑使用Java 8 streams来“简化”代码。