배쉬 정규식 캡처 그룹


22

문자열에서 여러 영숫자 값 (이 숫자는 다를 수 있음)을 일치시키고 bash 캡처 그룹 배열에 저장하려고합니다. 그러나 첫 번째 경기 만 받고 있습니다.

mystring1='<link rel="self" href="/unix//api/clouds/1/instances/1BBBBBB"/> dsf <link rel="self" href="/unix//api/clouds/1/instances/2AAAAAAA"/>'

regex='/instances/([A-Z0-9]+)'

[[ $mystring1 =~ $regex ]]

echo ${BASH_REMATCH[1]}
1BBBBBB

echo ${BASH_REMATCH[2]}

보시다시피 그것은 내가 찾고있는 첫 번째 값과 일치하지만 두 번째 값과는 일치하지 않습니다.


1
의 출력을 반복하여 만족 echo "$mystring1" | grep -oE '/instances/([A-Z0-9]+)'하십니까?
— Jeff Schaller

4
아마도 유명한 것을 언급 할 가치가 있습니다 .regex post로 HTML을 구문 분석 할 수 없습니다 .
— Digital Trauma

답변:


22

bash에서 전역 일치를 수행 할 수 없다는 것은 부끄러운 일입니다. 당신은 이것을 할 수 있습니다 :

global_rematch() { 
    local s=$1 regex=$2 
    while [[ $s =~ $regex ]]; do 
        echo "${BASH_REMATCH[1]}"
        s=${s#*"${BASH_REMATCH[1]}"}
    done
}
global_rematch "$mystring1" "$regex" 
1BBBBBB
2AAAAAAA

문자열에서 일치하는 접두사를 잘라내어 다음 부분을 일치시킬 수 있습니다. 그것은 문자열을 파괴하지만, 함수에서 지역 변수이므로 누가 신경 써야합니다.

실제로 해당 함수를 사용하여 배열을 채울 것입니다.

$ mapfile -t matches < <( global_rematch "$mystring1" "$regex" )
$ printf "%s\n" "${matches[@]}"
1BBBBBB
2AAAAAAA

고마워-이것은 가능한 솔루션처럼 보입니다-문제는 bash 3.2에 존재하지 않는 mapfile입니다 ...
— Arthur Lyssenko


6

두 번째 배열 값을 얻으려면 정규식에 두 번째 괄호 세트가 있어야합니다.

mystring1='<link rel="self" href="/unix//api/clouds/1/instances/1BBBBBB"/> dsf <link rel="self" href="/unix//api/clouds/1/instances/2AAAAAAA"/>'

regex='/instances/([A-Z0-9]+).*/instances/([A-Z0-9]+)'

[[ $mystring1 =~ $regex ]]

$ echo ${BASH_REMATCH[1]}
1BBBBBB
$ echo ${BASH_REMATCH[2]}
2AAAAAAA

고마워, 그러나 나는 알려지지 않은 수의 가능한 일치를 찾고 있습니다.
— Arthur Lyssenko

1
여러 개의 일치 항목이 배열에 들어갈 것으로 예상했기 때문에 Q를 상향 조정했지만 실제로는 여러 개의 괄호 세트가 없으면 그렇지 않습니다.
— Jeff Schaller
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.