sed 정규식 텍스트 처리는 그룹화된 참조 교대 혼란을 캡처합니다.

sed 정규식 텍스트 처리는 그룹화된 참조 교대 혼란을 캡처합니다.

sed의 캡처 그룹 ALTERNATION이 예상대로 작동하지 않습니다.

교대 우선 순위가 가장 낮지만 혼란스럽게도 다음과 같습니다.

echo "abcd_aefghi" | sed -r "s/(a)(b)(c)(d)|(a)(e)(f)(g)/\8/g;"

observed result --> _ghi
expected result --> error: invalid reference \8 RHS

a--bcd | # Logical alternation (Not bitwise!!)
#must be different separated logical state processing!! 
#not involvement of look behind registered reference grouping Counting!!
a--efg ;

반품

sed -r "s/(a)((b)(c)(d)|(e)(f)(g))/\8/;"
observed result --> _ghi

더욱 혼란스러운 경우

sed -r "s/(a)(b)(c)(d)()|((a)(e)(f)(g))/\8/g"

observed result --> _ehi

또한 더 혼란스럽습니다.

sed -r "s/(a)(b)(c)(d)()||||i am Not comment, Whats going here?|||||||((a)(e)(f)(g))/\8/g"

observed result --> _ehi
expected result --> full parsing error, because "||"

최악인 건 내부 그룹 매칭이다.

echo "aBcB_aCfC" | sed -r "s/(a)((B)(c)(\1)|(C)(f)(\1))/\4/g;"
#Infield twin uppercase's must match!
observed result --> aBcB_aCfC
expected result --> c_f

perl -pe같은 질문을 반복하세요!

문제는 교대 기호를 인식한 후 카운트를 재설정하지 않고 참조 카운트가 교대 범위를 벗어나는 것입니다.

Fedora 20의 sed 버전 4.2.2.

물론 제가 여기서 드리고 있는 질문은 매우 일반적이고 기본적인 질문입니다.

실제 스크립트는 긴 텍스트에 대한 매우 복잡한 원시 구문 분석입니다.

나의 초기 목표는 각 교대 질량 그룹의 네 번째 요소를 인쇄하는 것이었습니다. 이제 매칭을 분할해야 하므로 코드 크기가 크게 늘어납니다.

누군가 내 혼란을 줄일 수 있습니까?

답변1

\x정규식에서 여는 중괄호 발생에 따라 왼쪽에서 오른쪽으로 번호가 매겨진 x번째 캡처링 그룹에서 캡처된 항목으로 확장됩니다 .

echo "abcd_aefghi" | sed -r "s/(a)(b)(c)(d)|(a)(e)(f)(g)/\8/g;"
                               1  2  3  4   5  6  7  8

이 정규식은 두 번 일치합니다. 일단 열리면 abcd(8번째 캡처링 그룹은 아무것도 캡처하지 않음), 일단 열리면 aefg8번째 캡처링 그룹은 g. So 는 abcd아무것도 아닌 것으로 대체되고 and aefg는 변경되지 않은 상태로 유지되므로 예상한 결과를 g얻을 수 있습니다 ._hi_ghi

존재하다:

sed -r "s/(a)(b)(c)(d)()|((a)(e)(f)(g))/\8/g"
          1  2  3  4  5  67  8  9  10

알겠습니다 . 이제 그룹_ehi 8 이기 때문입니다 .(e)

sed -r "s/(a)(b)(c)(d)()||||i am Not comment, Whats going here?|||||||((a)(e)(f)(g))/\8/g"
          1  2  3  4  5                                               67  8  9  10

차이 없음. (표시되지는 않지만) 로 인해 ||및 사이에 빈 일치 항목이 있고 끝에 추가 일치 항목이 있습니다(및 일부는 와 일치 h) .iperl

교대 연산자를 기준으로 숫자 재설정그다지 유용한 API는 아닐 것입니다. 예제가 교대로 네 번째 캡처링 그룹과 일치하는 항목으로 확장하려면 언제든지 다음을 수행할 수 있습니다 .

sed -r 's/(a)(b)(c)(d)|(a)(e)(f)(g)/\4\8/g'
          1  2  3  4   5  6  7  8

이것은 당신에게도 같은 것을 줄 것입니다perl~의:

perl -lpe 's/(?|(a)(b)(c)(d)|(a)(e)(f)(g))/\4/g'
                1  2  3  4   1  2  3  4

(where는 \4무엇으로 확장될 수 있거나 캡처될 수 (d)있음 (g)).

답변2

내가 이해하는 바에 따르면, 코드가 복잡해지고 실제 문제가 해결되지 않기 때문에 주어진 답변에 만족하지 못하는 것 같습니다. 실제 문제를 모르고 도움을 드리기는 어렵습니다.

각 교대의 네 번째 부분을 보존하려면 아마도 다른 작업을 수행해야 할 것입니다.

sed -r 's/abcd|aefg/\n&/g;s/\n...//g'

각각의 일치 항목을 새 줄로 표시하고 두 번째 패스에서는 원하지 않는 세 문자가 포함된 새 줄을 제거합니다(이것은 sedGNU에서만 작동하지만 다른 문자로도 비슷한 작업을 수행할 수 있습니다 sed).

이 접근 방식은 코드를 증폭시키지 않습니다. 때로는 일을 다르게 해야 할 때도 있습니다. 물론 문자만 사용하는 대신 그룹을 사용하여 이 작업을 수행할 수도 있습니다.

그러나 이것이 실제 문제를 해결하지 못하는 경우(그리고 어떻게 적응해야 할지 모르는 경우) 예제 데이터를 사용하여 실제 문제를 알려주십시오.

관련 정보