[java] 공백 일치 정규식-Java

정규식 용 Java API는 \s공백과 일치 하는 상태입니다 . 따라서 정규식 \\s\\s은 두 개의 공백과 일치해야합니다.

Pattern whitespace = Pattern.compile("\\s\\s");
matcher = whitespace.matcher(modLine);
while (matcher.find()) matcher.replaceAll(" ");

이것의 목적은 두 개의 연속 된 공백의 모든 인스턴스를 단일 공백으로 바꾸는 것입니다. 그러나 이것은 실제로 작동하지 않습니다.

정규식이나 “공백”이라는 용어에 대해 심각한 오해가 있습니까?



답변

예, 다음 결과를 가져와야합니다 matcher.replaceAll().

String result = matcher.replaceAll(" ");
System.out.println(result);


답변

UTS # 18의 RL1.2\s 를 충족하기 위해 반드시 필요한 경우에도 Java에서 고유 문자 집합의 공백을 일치시키기 위해 Java를 사용할 수 없습니다. Java는 유니 코드 공백 속성을 지원하지 않기 때문입니다 . 안타깝게도 표준을 준수하지 않습니다.

유니 코드는 26 개의 코드 포인트를 \p{White_Space}다음 과 같이 정의합니다 . 그 중 20 개는 다양한 종류의 \pZ GeneralCategory = Separator 이고 나머지 6 개는 \p{Cc} GeneralCategory = Control 입니다.

공백은 매우 안정적인 속성이며 동일한 속성은 거의 영원히 존재했습니다. 그럼에도 불구하고 Java에는 이들에 대한 유니 코드 표준을 준수하는 속성이 없으므로 대신 다음과 같은 코드를 사용해야합니다.

String whitespace_chars =  ""       /* dummy empty string for homogeneity */
                        + "\\u0009" // CHARACTER TABULATION
                        + "\\u000A" // LINE FEED (LF)
                        + "\\u000B" // LINE TABULATION
                        + "\\u000C" // FORM FEED (FF)
                        + "\\u000D" // CARRIAGE RETURN (CR)
                        + "\\u0020" // SPACE
                        + "\\u0085" // NEXT LINE (NEL) 
                        + "\\u00A0" // NO-BREAK SPACE
                        + "\\u1680" // OGHAM SPACE MARK
                        + "\\u180E" // MONGOLIAN VOWEL SEPARATOR
                        + "\\u2000" // EN QUAD 
                        + "\\u2001" // EM QUAD 
                        + "\\u2002" // EN SPACE
                        + "\\u2003" // EM SPACE
                        + "\\u2004" // THREE-PER-EM SPACE
                        + "\\u2005" // FOUR-PER-EM SPACE
                        + "\\u2006" // SIX-PER-EM SPACE
                        + "\\u2007" // FIGURE SPACE
                        + "\\u2008" // PUNCTUATION SPACE
                        + "\\u2009" // THIN SPACE
                        + "\\u200A" // HAIR SPACE
                        + "\\u2028" // LINE SEPARATOR
                        + "\\u2029" // PARAGRAPH SEPARATOR
                        + "\\u202F" // NARROW NO-BREAK SPACE
                        + "\\u205F" // MEDIUM MATHEMATICAL SPACE
                        + "\\u3000" // IDEOGRAPHIC SPACE
                        ;        
/* A \s that actually works for Java’s native character set: Unicode */
String     whitespace_charclass = "["  + whitespace_chars + "]";    
/* A \S that actually works for  Java’s native character set: Unicode */
String not_whitespace_charclass = "[^" + whitespace_chars + "]";

이제 사용할 수 있습니다 whitespace_charclass + "+"당신의 패턴으로 replaceAll.


모든 것에 대해 죄송합니다. Java의 정규식은 고유 한 고유 문자 집합에서 잘 작동하지 않으므로 실제로 작동하도록하려면 이국적인 후프를 거쳐야합니다.

당신이 공백이 나쁜 생각한다면, 당신은 당신이 얻을 무엇을해야 볼 수 \w\b마지막으로 제대로 작동하도록!

예, 가능합니다. 그리고 예, 그것은 엉망진창입니다. 그것은 자선 활동입니다. 표준을 준수하는 Java 용 정규식 라이브러리를 얻는 가장 쉬운 방법은 ICU에 JNI를 사용하는 것입니다. OraSun은 측정하지 않기 때문에 Google이 Android에서하는 일입니다.

그렇게하고 싶지 않지만 여전히 Java를 고수하고 싶다면, 최소한 UTSRL1.2a 요구 사항을 준수하기 위해 Java의 패턴을 “수정”하는 프런트 엔드 정규식 재 작성 라이브러리가 있습니다. # 18, 유니 코드 정규식 .


답변

Java의 경우 (php가 아니라 javascript가 아니라 기타) :

txt.replaceAll("\\p{javaSpaceChar}{2,}"," ")


답변

Regexbuddy (정규식 개발자 응용 프로그램) 포럼에 질문을 보냈을 때 \ s Java 질문에 대해 더 정확한 답변을 받았습니다.

“메시지 작성자 : Jan Goyvaerts

Java에서 \ s, \ d 및 \ w는 ASCII 문자 만 포함합니다. … 이것은 Java의 버그가 아니라 정규 표현식으로 작업 할 때 알아야 할 많은 것 중 하나입니다. 모든 유니 코드 공백과 줄 바꿈을 일치 시키려면 Java에서 [\ s \ p {Z}]를 사용할 수 있습니다. RegexBuddy는 아직 \ p {javaSpaceChar} ([\ s \ p {Z}]와 정확히 동일한 문자와 일치)와 같은 Java 관련 속성을 지원하지 않습니다.

… \ s \ s는 입력이 ASCII 전용 인 경우 두 개의 공백과 일치합니다. 진짜 문제는 그 질문에 받아 들여진 대답이 지적한 것처럼 OP의 코드에 있습니다. “


답변

나를 위해 일하는 것 같습니다.

String s = "  a   b      c";
System.out.println("\""  + s.replaceAll("\\s\\s", " ") + "\"");

인쇄됩니다 :

" a  b   c"

코드 대신 이것을 의도했다고 생각합니다.

Pattern whitespace = Pattern.compile("\\s\\s");
Matcher matcher = whitespace.matcher(s);
String result = "";
if (matcher.find()) {
    result = matcher.replaceAll(" ");
}

System.out.println(result);


답변

목적을 위해 다음 스 니펫을 사용할 수 있습니다.

import org.apache.commons.lang3.StringUtils;

StringUtils.normalizeSpace(string);

이렇게하면 간격이 단일로 정규화되고 시작 및 후행 공백도 제거됩니다.

String sampleString = "Hello    world!";
sampleString.replaceAll("\\s{2}", " "); // replaces exactly two consecutive spaces
sampleString.replaceAll("\\s{2,}", " "); // replaces two or more consecutive white spaces


답변

Pattern whitespace = Pattern.compile("\\s\\s");
matcher = whitespace.matcher(modLine);

boolean flag = true;
while(flag)
{
 //Update your original search text with the result of the replace
 modLine = matcher.replaceAll(" ");
 //reset matcher to look at this "new" text
 matcher = whitespace.matcher(modLine);
 //search again ... and if no match , set flag to false to exit, else run again
 if(!matcher.find())
 {
 flag = false;
 }
}