"U39,R11,U50-U55,U99
"과 같은 일부 문자열 유형의 데이터가 있습니다.범위를 확장하는 방법 012 - w d +
하이픈으로 표시된 범위를 확장하여 "U39,R11,U50,U51,U52,U53,U54,U55,U99
"으로 변경하는 방법은 무엇입니까?
자바 정규 표현식을 사용하여 "-"및 "-"앞에 숫자와 문자 접두사를 파악한 다음 루프를 사용하여 처음부터 끝까지 숫자를 인쇄합니다. 더 나은 해결책이 있습니까?
"U39,R11,U50-U55,U99
"과 같은 일부 문자열 유형의 데이터가 있습니다.범위를 확장하는 방법 012 - w d +
하이픈으로 표시된 범위를 확장하여 "U39,R11,U50,U51,U52,U53,U54,U55,U99
"으로 변경하는 방법은 무엇입니까?
자바 정규 표현식을 사용하여 "-"및 "-"앞에 숫자와 문자 접두사를 파악한 다음 루프를 사용하여 처음부터 끝까지 숫자를 인쇄합니다. 더 나은 해결책이 있습니까?
이 같은 목록의 항목 스트림은 (오히려 기존의 반복보다는) 자바 8 스트림 꽤 좋은 사용 사례입니다 나는 합리적인 방법으로 그렇게 할 것이라고 생각한다 :
String.split(",")
을 사용합니다.ArrayList<String>
(labelsOut
) 결과를 저장하십시오.labelsIn
배열이고, 각 요소 :
[A-Z][0-9]+
상기 labelsOut
목록에 추가 할 경우. 이 패턴 ([A-Z])([0-9]+)-\1([0-9]+)
(match
Matcher
객체 호출을) 일치하는 경우 그렇지high
에 low
에서 low
및 high
모든 번호를 n
(Integer.valueOf(match.group(2))
및 Integer.valueOf(match.group(3))
을 사용하여) 번호를 추출 labelsOut
목록에 String.format("%s%d", match.group(1), n)
를 추가합니다.labelsOut
목록에서 ","
.당신은 당신이 맞는 볼 경우 0 개 이상의 공백 ","
주변의 문자 (\s*
)와 "-"
를 허용함으로써 정규 표현식을 조금 일반화 할 수 있습니다.
위의 절차는 성능이 아닌 교훈적인 명확성에 맞게 최적화되어 있습니다. 원하는 경우 중간 결과 중 일부를 제거 할 수 있습니다. Java 8 streams을 사용하여 코드를 "간소화"할 수도 있습니다.
고마워요! String.format ("% s % d", match.group (1), n)의 의미가 확실하지 않습니다. 결과는 무엇입니까? –
'match.group (1)'은 일치하는 문자 (정규 표현식에서 처음 괄호 안에있는 것)를 반환합니다 (예 :' "U"'). 'String.format'은'% s'을 인수 # 1로 전달 된 문자열로 대체하고 '% d'는 인수 # 2로 전달 된 정수 표현으로 대체합니다. 그러므로'n = 51'이라면, 형식화 된 문자열은''U51''을 읽을 것입니다. 보고 그것을 시도하십시오. – 5gon12eder
늦어서 죄송 합니다만, 말씀 드린대로 모든 숫자 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");
}
인쇄합니다 U23,R45,U12,U13,U14,U15,R7
답변 해 주셔서 감사합니다. 스트림을 그렇게 사용하는 방법을 본 적이 없습니다. –
실제로 훨씬 좋습니다! –
@BaochengLi 대단히 기쁩니다. 유용하다고 생각합니다. 스트림은 매우 익숙해지면 매우 강력하고 직관적입니다. – sprinter
만약'X50-A11'이 있다면? –
제목이 내가 얻지 못한 말장난인가? 미래의 사용자가 "다양한 레이블을 확장하는 방법"으로 변경하는 데 도움이 될 것이라고 생각합니다. – 5gon12eder
@ 5gon12eder "pun": LOL. - 내가 제 1 언어에서 문자 그대로 번역한다면 나는 아마도 "본딩 스트로크"를 생각해 낼 것입니다. 그리고 프랑스 인은 "노동 조합"을 만들 수도 있습니다. – laune