하위 문자열 및 정규식

하위 문자열 및 정규식

문자열이 포함된 변수가 있고 다른 하위 문자열을 기준으로 해당 위치를 기준으로 하위 문자열을 추출하고 싶습니다. 내 솔루션은 문자열이 함수에 매개 변수로 전송되지 않는 한 작동하는 것 같습니다. 나는 bash 쉘을 사용하고 있습니다.

#!/usr/bin/bash

var0="-a check one two three"
var1="check"

function getsubstr() {
echo ${*#*"${2}"} 
}

# this prints 'one two three' which is what I want
echo ${var0#*"${var1}"}

# this prints '-a one two three', not what I want.
getsubstr $var0

echo $*함수를 넣으면 getsubstr(-> '-a check one two three')와 같은 문자열이 인쇄되고, 함수를 넣으면 (-> 'check')와 같은 문자열이 인쇄됩니다. 따라서 두 경우 모두 동일한 하위 문자열을 인쇄하도록 요청하는 것 같습니다.$var0echo $2getsubstr$var1

또 다른 어려움은 내가 사용하고 있는 함수 echo ${*#*"${2}"}에 없는 경우에도 똑같은 결과를 얻는다는 것입니다.getsubstrecho ${*%"${2}"*}

이 동작을 이해하는 데 도움을 주시면 대단히 감사하겠습니다.

${*:3}그런데 함수 내에서 getsubstr내가 원하는 하위 문자열을 반환하는 것이 가능하다는 것을 알고 있지만 이해 #*<regexp>하고 %<regextp>*행동하려고 노력하고 있습니다.

답변1

getsubstr $var05개의 매개변수를 함수에 전달하고 있습니다 .
또한 $* 및 $@는 모두를 테스트합니다.$1$2$ 등...인수 개체#무늬.

정규 표현식에 관하여 bash: 마지막에 몇 가지 예를 추가했습니다. 그런데 "*"는 단지특수 정규식 문자정규식 컨텍스트에서 사용되는 경우, 즉. 그것을 사용할 때 =~. * in이 처음 사용될 때 ${*별표를 특별히 사용하는 방법 은 다음과 같습니다.(의사) 이름var는 모든 변수의 연결로 확장됩니다: $1 $2 $... etc...
별표의 두 번째 사용은 다음을 #*"${2}"의미합니다."$2" 앞에는 아무것도 없습니다, 전달된 각 $1 등 인수와 개별적으로/개별적으로 일치됩니다.

다음 스크립트는 $@ 및 $*(예:)에 도움이 될 수 있습니다.

#!/bin/bash
#   
getsubstr() {
  echo -n " ${#@} args";
  [[ "$1$2$3$4$5$6" == *\ * ]] && echo " (with embedded spaces)" || echo " (no spaces)"
  echo '                  "${*}"          '\|"${*}"\|
  echo '                   ${*}           '\|${*}\|
  echo '                  "${@}"          '\|"${@}"\|
  echo '                   ${@}           '\|${@}\|
  echo '                  "${*#*"${2}}"   '\|"${*#*"${2}"}"\|
  echo '                   ${*#*"${2}}    '\|${*#*"${2}"}\|
  echo '                  "${@#*"${2}}"   '\|"${@#*"${2}"}"\|
  echo '                   ${@#*"${2}}    '\|${@#*"${2}"}\|
  echo '                        ${*#B}    '\|${*#B}\|
  echo '                       "${*#B}"   '\|"${*#B}"\|
  echo '                        ${@#B}    '\|${@#B}\|
  echo '                       "${@#B}"   '\|"${@#B}"\|
}
var0="a B c      "
echo
echo -n "Passing "; getsubstr "$var0" ; echo
echo -n "Passing "; getsubstr  $var0  ; echo
echo -n "Passing "; getsubstr "$var0" "$var0" ; echo
echo -n "Passing "; getsubstr  $var0   $var0  ; echo
echo
exit 
###################################################################

정규식bash

# Regex checks: "=~" uses extended regular expression
#+  Parenthesized subexpressions within the regular expression are saved
#+  in the array variable BASH_REMATCH
#+  $BASH_REMATCH / ${BASH_REMATCH[0]} is the string matching the entire regular expression. 
#+  ${BASH_REMATCH[n]} is the sub string matching the nth parenthesized subexpression

  [[ "abcdef" =~ (.)(.)(.) ]] && echo "# $BASH_REMATCH"
# abc

  [[ "abcdef" =~ (.)(.)(.) ]] && echo "# ${BASH_REMATCH[0]}"
# abc

  [[ "abcdef" =~ (.)(.)(.) ]] && echo "# ${BASH_REMATCH[2]}"
# b

  [[ "abcdef" =~ (.)(.)(.) ]] && echo "# ${BASH_REMATCH[@]}"
# abc a b c

답변2

설명으로 업데이트됨

이러한 유형의 동작이 나타나는 이유는 모든 위치 매개변수로 확장되기 $*때문 입니다 . 실행하려고 하면$@$1$2매개변수 확장(PE) 이 두 특수 변수 중 하나에서 각 위치 인수에 PE를 적용하고아니요단일 문자열.

에서 발췌man bash

${매개변수#단어}
일치하는 접두사 패턴을 제거합니다. 경로 이름 확장과 마찬가지로 단어가 확장되어 패턴을 생성합니다. 패턴이 매개변수 값의 시작 부분과 일치하는 경우 확장 결과는 #'' case) or the longest matching pattern (the가장 짧은 일치 패턴이 제거된 매개변수의 확장된 값입니다(##'' 사례). 인수가 @ 또는 *인 경우 패턴 제거 작업이 각 위치 인수에 차례로 적용되고 확장이 결과 목록이 됩니다.

본질적으로 당신이 하고 있는 일은 다음과 같습니다:

getsubstr() { 
  tmp=$2
  for arg; do 
    printf "%s " ${1#*$tmp}
    shift
  done
}

다음 함수는 이제 PE를 일반 변수에 한 번 적용하므로 임시 변수를 설정하여 $*작동합니다 .$tmp

getsubstr() {
  tmp=$*
  echo ${tmp#*$2}
}

폴리스티렌

functionPOSIX가 아니기 때문에 사용하지 마세요. ()이미 함수 이름 뒤에 사용하고 있다면 전혀 필요하지 않습니다.

폴리페닐렌 설파이드

이는 실제로 다음과 같습니다.일반적인 표현대신에구형 표현. 보다 공식적으로는 이를 다음과 같이 부릅니다.매개변수 확장

관련 정보