매개변수가 중첩된 패턴을 식별하는 방법

매개변수가 중첩된 패턴을 식별하는 방법

일부 텍스트와 함께 패턴(중첩 매개변수 포함)을 묶기 위해 sed에서 사용할 몇 가지 정규식을 찾으려고 합니다.

기본적인 예는 다음과 같습니다.

length(bill_cycle)

정규 표현식은 다음을 제공해야 합니다.

length(cast(bill_cycle as string))

여기서는 로 시작하는 것을 검색 하고 와 관련된 결말을 length(​​찾습니다 . 그런 다음 중간에 있는 콘텐츠 를)length(bill_cyclecast(bill_cycle as string)

변수(이 경우 some(somethiing))에 다음과 같은 중첩된 매개변수가 있더라도

length(some(somethiing))

정규 표현식은 다음을 제공해야 합니다.

length(cast(some(somethiing) as string))

나는 UNIX 스크립트나 작동하는 다른 명령에 열려 있습니다. 어떤 도움이라도 대단히 감사하겠습니다.

답변1

Perl이 구출하러 옵니다!

perl -MText::Balanced=extract_bracketed \
     -ne 'if (/length(\(.*)/) {
              ($arg) = (extract_bracketed(($1 =~ /\((.*)\)/)[0]))[1];
              print "length(cast($arg as string))\n";
          } else { print }' -- input.file > output.file

핵심 모듈을 사용합니다.텍스트::균형문자열에서 균형 구분 기호가 있는 하위 문자열을 추출합니다.

답변2

사용 perl및 재귀 매칭:

$ cat ip.txt
length(bill_cycle)
length(some(somethiing))

$ perl -pe 's/length(\(((?:[^()]++|(?1))++)\))/length(cast($2 as string))/' ip.txt 
length(cast(bill_cycle as string))
length(cast(some(somethiing) as string))

바라보다https://www.rexegg.com/regex-recursion.html재귀가 어떻게 작동하는지 이해합니다.

답변3

이것은 괄호의 패턴 일치를 사용하지 않고 이를 계산하는 awk 스크립트입니다. 또한 각 줄의 여러 항목과 일치합니다.

BEGIN { 
    p = "length"
}

{
    row = $0
    while (row ~ p"\\(") {
        # get the substring from pattern to the end of the line
        # and split to array with closing parenthesis separator

        x = substr(row, index(row,p) + length(p))
        split(x, a, ")")
        res = p

        # loop for array items and append them to substring
        # until we have a string with same number of
        # opening and closing parentheses.

        for (i=1;i<=length(a);i++) {

            res = res a[i] (i==length(a)? "": ")")

            if (gsub(/\(/,"(",res) == gsub(/\)/,")",res)) {
                print res
                break
            }
        }
        
        # will test again the rest of the row
        row = substr(x, length(p))
    }
}

몇 가지 기본 테스트

> cat file
some text length(a(b)) testing another occurence length(a))
function(length(c(d(e(f(1), 2)))) testinglength(x)
x length(y))
x length(((y))
length(length(1))

> awk -f tst.awk file
length(a(b))
length(a)
length(c(d(e(f(1), 2))))
length(x)
length(y)
length(length(1))

관련 정보