\ R이 Java 8과 Java 9의 정규식에서 다르게 작동하는 이유는 무엇입니까?
다음 코드는 Java 8 및 9 모두에서 컴파일되지만 다르게 작동합니다.
class Simple {
static String sample = "\nEn un lugar\r\nde la Mancha\nde cuyo nombre\r\nno quiero acordarme";
public static void main(String args[]){
String[] chunks = sample.split("\\R\\R");
for (String chunk: chunks) {
System.out.println("Chunk : "+chunk);
}
}
}
Java 8로 실행하면 다음이 반환됩니다.
Chunk :
En un lugar
de la Mancha
de cuyo nombre
no quiero acordarme
그러나 Java 9로 실행하면 출력이 다릅니다.
Chunk :
En un lugar
Chunk : de la Mancha
de cuyo nombre
Chunk : no quiero acordarme
왜?
자바 문서는 유니 코드 표준을 준수 벗어났습니다. Javadoc \R
은 일치해야하는 내용을 잘못 이해합니다 . 읽습니다.
\R
모든 유니 코드 줄 바꿈 시퀀스는 다음과 같습니다.\u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]
그 Java 문서는 버그가 있습니다. 그것에서 R1.6 줄 바꿈 섹션 정규 표현식에, 유니 코드 기술 표준 # 18 분명히 말한다 :
위에 나열된 모든 줄 끝 문자 및 시퀀스 (예 : # 1)를 일치시키기 위해 "\ R"과 같은 정규식 메타 문자가있는 것이 좋습니다. 이것은 다음 표현식과 동등한 것에 해당합니다. 이 표현은 백업을 피해야하기 때문에 약간 복잡합니다.
(?:\u{D A}|(?!\u{D A})[\u{A}-\u{D}\u{85}\u{2028}\u{2029}]
즉, 단지 두 개의 코드 포인트 CR + LF (캐리지 리턴 + 바꿈) 시퀀스를 일치시킬 수 그렇지 는 것을 제공되는 세트에서 단일 코드 포인트를 하지 후 바꿈 뒤에 만 단지 캐리지 리턴 . 백업이 허용되지 않기 때문입니다 . CRLF가 \R
제대로 작동하려면 원자 적이어야합니다 .
따라서 Java 9는 더 이상 R1.6이 강력하게 권장하는 사항을 따르지 않습니다. 또한 Java 8에서하지 말아야 할 일을하고 있고하지 말아야 할 일을하고 있습니다.
Sherman (읽기 : Xueming Shen)에게 다시 외칠 때가 된 것 같습니다. 나는 이전에 공식적인 적합성의 핵심적인 문제에 대해 그와 함께 일했습니다.
Java 8의 버그 였고 수정되었습니다 : JDK-8176029 : "Linebreak matcher가 javadoc에 명시된 패턴과 동일하지 않습니다" .
'IT TIP' 카테고리의 다른 글
IE6 (IE7)의 JSON (0) | 2020.10.14 |
---|---|
음수 값을 확인하는 대신 uint로 캐스팅하여 범위 확인을 수행하는 것이 더 효율적입니까? (0) | 2020.10.14 |
생성자 경고에서 이것을 누출 (0) | 2020.10.14 |
부호있는 / 부호없는 비교 (0) | 2020.10.14 |
__weak 참조와 __block 참조의 차이점은 무엇입니까? (0) | 2020.10.14 |