![Bash 정규식 캡처 그룹](https://linux55.com/image/79995/Bash%20%EC%A0%95%EA%B7%9C%EC%8B%9D%20%EC%BA%A1%EC%B2%98%20%EA%B7%B8%EB%A3%B9.png)
문자열에서 여러 영숫자 값을 일치시키고(이 숫자는 다를 수 있음) 이를 bash 캡처 그룹 배열에 저장하려고 합니다. 그러나 첫 번째 일치 항목만 얻습니다.
mystring1='<link rel="self" href="/api/clouds/1/instances/1BBBBBB"/> dsf <link rel="self" href="/api/clouds/1/instances/2AAAAAAA"/>'
regex='/instances/([A-Z0-9]+)'
[[ $mystring1 =~ $regex ]]
echo ${BASH_REMATCH[1]}
1BBBBBB
echo ${BASH_REMATCH[2]}
보시다시피, 제가 찾고 있는 첫 번째 값과 일치하지만 두 번째 값은 일치하지 않습니다.
답변1
불행히도 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
답변2
두 번째 배열 값을 얻으려면 정규식에서 두 번째 대괄호 세트를 사용해야 합니다.
mystring1='<link rel="self" href="/api/clouds/1/instances/1BBBBBB"/> dsf <link rel="self" href="/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