동일한 패턴의 여러 그룹을 캡처해야합니다. 다음 문자열이 있다고 가정합니다.
HELLO,THERE,WORLD
그리고 다음 패턴을 작성했습니다.
^(?:([A-Z]+),?)+$
내가 원하는 것은 그룹 1이 “HELLO”, 그룹 2는 “THERE”, 그룹 3은 “WORLD”가되도록 모든 단어를 캡처하는 것입니다. 내 정규식이 실제로 마지막 하나만 캡처하는 ” 세계”.
여기에서 정규 표현식을 테스트 하고 있으며 Swift와 함께 사용하고 싶습니다 (스위프트에 어떻게 든 중간 결과를 얻을 수있는 방법이있을 수 있으므로 사용할 수 있습니까?)
업데이트 : 사용하고 싶지 않습니다 split
. 이제 마지막 그룹뿐만 아니라 패턴과 일치하는 모든 그룹을 캡처하는 방법 만 있으면됩니다.
답변
패턴에 하나의 그룹이 있으면 해당 그룹에서 정확한 결과를 하나만 얻을 수 있습니다. 캡처 그룹이 패턴에 의해 반복되는 경우 ( +
주변 비 캡처 그룹 에서 수량자를 사용함 ) 일치하는 마지막 값만 저장됩니다.
패턴의 모든 일치 항목 을 찾기 위해 언어의 정규식 구현 함수를 사용해야합니다 . 그런 다음 비 캡처 그룹의 앵커와 수량자를 제거해야합니다 (비 캡처 그룹 자체도 생략 할 수 있음).
또는 정규식을 확장하고 결과에서 얻고 자하는 그룹당 하나의 캡처 그룹을 패턴에 포함 시키십시오.
^([A-Z]+),([A-Z]+),([A-Z]+)$
답변
이런 게 필요한 것 같아요 ….
b="HELLO,THERE,WORLD"
re.findall('[\w]+',b)
Python3에서 반환되는
['HELLO', 'THERE', 'WORLD']
답변
답변에 단락 2의 추가 예를 제공하기 위해. 한 그룹을 사용하여 세 경기를하는 것보다 한 경기에서 세 그룹을 얻는 것이 얼마나 중요한지 잘 모르겠습니다. 예 : 그루비에서 :
def subject = "HELLO,THERE,WORLD"
def pat = "([A-Z]+)"
def m = (subject =~ pat)
m.eachWithIndex{ g,i ->
println "Match #$i: ${g[1]}"
}
Match #0: HELLO
Match #1: THERE
Match #2: WORLD
답변
Byte Commander의 답변을 읽은 후 가능한 약간의 개선 사항을 소개하고 싶습니다.
미리 결정된 한 두 n
단어 중 하나와 일치하는 정규 표현식을 생성 할 수 있습니다 n
. 예를 들어 1 ~ 3 개의 단어를 일치 시키려면 정규 표현식 :
^([A-Z]+)(?:,([A-Z]+))?(?:,([A-Z]+))?$
다음 문장을 1 개, 2 개 또는 3 개의 캡처 그룹과 일치시킵니다.
HELLO,LITTLE,WORLD
HELLO,WORLD
HELLO
Regex101 에서이 정규식에 대한 자세한 설명을 볼 수 있습니다 .
내가 말했듯이 좋아하는 언어를 사용하여 원하는 그룹에 대해이 정규식을 생성하는 것은 매우 쉽습니다. 나는 빠른 사람이 아니기 때문에 다음은 루비 예제입니다.
def make_regexp(group_regexp, count: 3, delimiter: ",")
regexp_str = "^(#{group_regexp})"
(count - 1).times.each do
regexp_str += "(?:#{delimiter}(#{group_regexp}))?"
end
regexp_str += "$"
return regexp_str
end
puts make_regexp("[A-Z]+")
즉,이 경우 정규식을 사용하지 않는 것이 좋습니다 split
. 필요에 따라 단순한 토큰 화 패턴에서 일부 토큰 화 패턴 까지 다른 많은 훌륭한 도구 가 있습니다. IMHO, 정규 표현식은 그중 하나가 아닙니다. 예를 들어 루비에서는 str.split(",")
또는 같은 것을 사용합니다.str.scan(/[A-Z]+/)
답변
주요 차이점은 반복 된 그룹 을 캡처하는 대신 캡처 된 그룹을 반복하는 것입니다 .
이미 알고 있듯이 캡처 된 그룹을 반복하면 마지막 반복 만 캡처된다는 차이점이 있습니다. 반복 된 그룹을 캡처하면 모든 반복이 캡처됩니다.
PCRE (PHP) :
((?:\w+)+),?
Match 1, Group 1. 0-5 HELLO
Match 2, Group 1. 6-11 THERE
Match 3, Group 1. 12-20 BRUTALLY
Match 4, Group 1. 21-26 CRUEL
Match 5, Group 1. 27-32 WORLD
모든 캡처가 그룹 1에 있으므로 $1
교체 만하면됩니다.
이 정규식의 다음과 같은 일반적인 형식을 사용했습니다.
((?:{{RE}})+)
답변
실제로 여러 번 일치하는 하나의 캡처 그룹이 있습니다. 여러 캡처 그룹이 아닙니다.
자바 스크립트 (js) 솔루션 :
let string = "HI,THERE,TOM";
let myRegexp = /([A-Z]+),?/g; //modify as you like
let match = myRegexp.exec(string); //js function, output described below
while(match!=null){ //loops through matches
console.log(match[1]); //do whatever you want with each match
match = myRegexp.exec(bob); //find next match
}
산출:
HI
THERE
TOM
통사론:
// matched text: match[0]
// match start: match.index
// capturing group n: match[n]
보시다시피, 이것은 모든 경기에서 작동합니다.
답변
내 대답이 늦었다는 것을 알고 있지만 오늘 나에게 발생하며 다음 접근 방식으로 해결했습니다.
^(([A-Z]+),)+([A-Z]+)$
따라서 첫 번째 그룹 (([A-Z]+),)+
은 마지막 패턴 ([A-Z]+)
과 일치하는 마지막 패턴을 제외한 모든 반복 패턴 과 일치합니다. 그리고 이것은 문자열에서 반복되는 그룹의 수에 관계없이 동적입니다.