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번째 캡처링 그룹은 아무것도 캡처하지 않음), 일단 열리면 aefg
8번째 캡처링 그룹은 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
) .i
perl
교대 연산자를 기준으로 숫자 재설정그다지 유용한 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'
각각의 일치 항목을 새 줄로 표시하고 두 번째 패스에서는 원하지 않는 세 문자가 포함된 새 줄을 제거합니다(이것은 sed
GNU에서만 작동하지만 다른 문자로도 비슷한 작업을 수행할 수 있습니다 sed
).
이 접근 방식은 코드를 증폭시키지 않습니다. 때로는 일을 다르게 해야 할 때도 있습니다. 물론 문자만 사용하는 대신 그룹을 사용하여 이 작업을 수행할 수도 있습니다.
그러나 이것이 실제 문제를 해결하지 못하는 경우(그리고 어떻게 적응해야 할지 모르는 경우) 예제 데이터를 사용하여 실제 문제를 알려주십시오.