bash 정규식 다중 일치

bash 정규식 다중 일치

bash정규식 메시지를 구문 분석하고 그룹 캡처에 대한 일부 작업을 수행하는 멋진 작은 스크립트가 있습니다 .

regex='\((Closes|Resolves):\s([0-9]+)\)'
msg='Fixed a problem (Closes: 1234), (Resolves: 5678)'

if [[ $msg =~ $regex ]] ; then
  action="${BASH_REMATCH[1]}"
  issue="${BASH_REMATCH[2]}"
  do_something $action $issue
fi

이는 첫 번째 일치에 적합하지만 일치하는 항목이 여러 개인 경우 msg후속 일치 항목은 무시됩니다. 각 게임을 순환할 수 있는 방법이 있나요? 아니면 이제 생각을 시작할 시간 python인가요 perl?

답변1

내장 bash구문에서는 명시적으로 지원되지 않지만 일부 변수 대체 및 일부 재귀를 통해 쉽게 구현할 수 있습니다.

function do_something {
  echo $1 $2
}

function handlematches {
  regex='\((Closes|Resolves):\s([0-9]+)\)'
  msg=$1

  if [[ $msg =~ $regex ]] ; then
    action="${BASH_REMATCH[1]}"
    issue="${BASH_REMATCH[2]}"
    do_something "$action" "$issue"

    # Remove the first regex match and try again
    handlematches "${msg/${BASH_REMATCH[0]}/}"
  fi
}

message='Fixed a problem (Closes: 1234), (Resolves: 5678)'
handlematches "$message"

산출:

Closes 1234
Resolves 5678

답변2

~처럼스튜어트의 대답, 그러나 재귀적 접근 방식이 아닌 반복적 접근 방식을 사용합니다.

regex='\((Closes|Resolves): ([0-9]+)\)'
msg='Fixed a problem (Closes: 1234), (Resolves: 5678)'

while [[ $msg =~ $regex ]]; do
        action=${BASH_REMATCH[1]}
        issue=${BASH_REMATCH[2]}
        do_something "$action" "$issue"

        msg=${msg/"${BASH_REMATCH[0]}"/}
done

$msg정규식이 더 이상 일치하지 않을 때까지 문자열을 반복합니다 . 각 반복에서 일치하는 비트를 제거하기 위해 매개변수 대체가 사용됩니다 bash.

원본을 유지하려면 $msg먼저 다른 변수에 복사하세요.

그리고

do_something () {
        printf 'action=%s, issue=%s\n' "$1" "$2"
}

이 출력

action=Closes, issue=1234
action=Resolves, issue=5678

관련 정보