Nice programing

String.split ()을 사용하여 단어 쌍 추출

nicepro 2021. 1. 7. 21:20
반응형

String.split ()을 사용하여 단어 쌍 추출


주어진:

String input = "one two three four five six seven";

한 번에 String.split()(최대) 두 단어를 잡기 위해 작동하는 정규식이 있습니까?

String[] pairs = input.split("some regex");
System.out.println(Arrays.toString(pairs));

결과는 다음과 같습니다.

[one two, three four, five six, seven]

이 질문은 분할 정규식 에 관한 입니다. 그것은 것입니다 하지 솔루션 "또 다른 방식으로 작동하기"의 "해결 방법을 찾는"또는 기타에 대해.


현재 (Java 10 포함)를 사용하여 수행 할 수 split()있지만 실제로는이 접근 방식을 사용하지 마십시오. 이는 Java의 look-behind가 명백한 최대 길이를 가져야하기 때문에 버그에 기반한 것처럼 보이므로이 방법은 다음을 사용합니다 \w+. 이 제한을 존중하지 않고 어떻게 든 여전히 작동하므로 이후 릴리스에서 수정 될 버그 인 경우이 솔루션이 작동을 멈 춥니 다.

대신 정규식을 사용 Pattern하고 Matcher클래스를 사용 \w+\s+\w+하는 것 외에 더 안전한 것 외에도 그러한 코드를 상속 할 사람의 유지 관리 지옥을 피할 수 있습니다 ( " 항상 코드를 유지 관리하는 사람이 당신이 사는 곳을 아는 폭력적인 사이코 패스 인 것처럼 코딩하십시오 "). .


이것이 당신이 찾고있는 것입니까?
(당신은 대체 할 수 있습니다 \\w\\S모든 비 공백 문자를 포함하지만,이 예를 들어 나는 떠날 것이다 \\w그것으로 정규식을 쉽게 읽을 수 있기 때문에 \\w\\s다음 \\S\\s)

String input = "one two three four five six seven";
String[] pairs = input.split("(?<!\\G\\w+)\\s");
System.out.println(Arrays.toString(pairs));

산출:

[one two, three four, five six, seven]

\G이전 일치이고 (?<!regex)부정적인 lookbehind입니다.

에서 split우리가하려고하는

  1. 공백 찾기-> \\s
  2. 예측되지 않은-> (?<!negativeLookBehind)
  3. 한마디로-> \\w+
  4. 이전에 일치 (공백)-> \\G
  5. 그 전에-> \\G\\w+.

처음에 내가 혼란 스러웠던 것은 첫 번째 공간이 무시되기를 바라기 때문에 첫 번째 공간에서 어떻게 작동 할 것인가하는 것뿐이었습니다. 중요한 정보는 \\G시작시 String의 시작과 일치 한다는 것^ 입니다.

부정적인 모습 숨김 첫 번째 반복 정규식이 모양을 그래서 전에 (?<!^\\w+)먼저 공간이 있기 때문에 할 수 있습니다 ^\\w+전에 분할에 대한 일치하지 않을 수 있습니다. 다음 공간에는이 문제가 없으므로 일치되고 이에 대한 정보 ( 문자열 에서 위치 와 같은 input)가 저장되고 \\G나중에 다음 부정적인 조회에서 사용됩니다.

따라서 세 번째 공백의 경우 정규식은 이전에 일치하는 공백 \\G과 단어 가 있는지 확인 \\w+합니다. 이 테스트의 결과가 긍정적이기 때문에 네거티브 look-behind는 그것을 받아들이지 않을 것이므로이 공간은 일치하지 않을 것입니다. 그러나 4 번째 공간은 이전 공간이 저장된 것과 같지 않을 것이기 때문에이 문제 \\G가 없습니다 ( input문자열 에서 다른 위치를 가질 것입니다 ) .


또한 누군가가 세 번째 공간마다 분리하고 싶다면이 양식을 사용할 수 있습니다 (이 답변 조각을 게시했을 때 삭제 된 @maybeWeCouldStealAVan답변기반으로 )

input.split("(?<=\\G\\w{1,100}\\s\\w{1,100}\\s\\w{1,100})\\s")

100 대신 String에서 가장 긴 단어의 길이보다 큰 값을 사용할 수 있습니다.


예를 들어 매 3, 5, 7과 같이 모든 홀수로 분할하려는 경우 +대신 사용할 수도 있습니다.{1,maxWordLength}

String data = "0,0,1,2,4,5,3,4,6,1,3,3,4,5,1,1";
String[] array = data.split("(?<=\\G\\d+,\\d+,\\d+,\\d+,\\d+),");//every 5th comma 

작동하지만 최대 단어 길이를 미리 설정해야합니다.

String input = "one two three four five six seven eight nine ten eleven";
String[] pairs = input.split("(?<=\\G\\S{1,30}\\s\\S{1,30})\\s");
System.out.println(Arrays.toString(pairs));

나는 Pshemo의 대답을 더 좋아하고 짧고 임의의 단어 길이에 사용할 수 있지만 (@Pshemo가 지적했듯이) 2 개 이상의 단어 그룹에 적응할 수 있다는 장점이 있습니다.


이 날의 근무 (\w+\s*){2}\K\s예를 들어 여기에

  • 필수 단어 다음에 선택적 공백 (\w+\s*)
  • 두 번 반복 {2}
  • 이전에 일치하는 문자 무시 \K
  • 필요한 공간 \s

이것을 시도 할 수 있습니다.

[a-z]+\s[a-z]+

업데이트 :

([a-z]+\s[a-z]+)|[a-z]+

여기에 이미지 설명 입력

업데이트 :

 String pattern = "([a-z]+\\s[a-z]+)|[a-z]+";
 String input = "one two three four five six seven";

 Pattern splitter = Pattern.compile(pattern);
 String[] results = splitter.split(input);

 for (String pair : results) {
 System.out.println("Output = \"" + pair + "\"");

참조 URL : https://stackoverflow.com/questions/16485687/extracting-pairs-of-words-using-string-split

반응형