배쉬 정규식 캡처 그룹


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.