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
우리가하려고하는
- 공백 찾기->
\\s
- 예측되지 않은->
(?<!negativeLookBehind)
- 한마디로->
\\w+
- 이전에 일치 (공백)->
\\G
- 그 전에->
\\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
'Nice programing' 카테고리의 다른 글
Jenkins 및 Git 스파 스 체크 아웃 (0) | 2021.01.07 |
---|---|
캡슐화와 추상화의 차이점 (0) | 2021.01.07 |
해결 :이 테이블은 고유 한 열을 포함하지 않습니다. (0) | 2021.01.07 |
ReferenceError : 모듈이 정의되지 않았습니다-Angular / Laravel 앱을 사용한 Karma / Jasmine 구성 (0) | 2021.01.07 |
Xamarin과 Telerik의 기본 스크립트의 차이점 (0) | 2021.01.07 |