2013-03-05 2 views
0

GNU sed 버전 4.2.1을 사용 중입니다. 다른 두 문자열로 구분 된 문자열을 추출하기 위해 욕심이없는 SED 정규식을 작성하려고합니다. 단락 문자 문자열은 단일 문자 때이 용이하다 : 그 예에서다른 문자열로 구분 된 문자열을 추출하는 SED 정규식을 작성하려면 어떻게합니까?

s:{\([^}]*\)}:\1:g 

문자열에 의해 구분되는 '{'왼쪽에 '}'오른쪽에. 구분 문자열이 여러 문자 인 경우

은 '{{{'와 '}}}'나는 이런 식으로 위의 표현 조정할 수 있습니다 말 :

s:{{{\([^}}}]*\)}}}:\1:g 

그래서 중심의 표현이 아무것도 포함하지 않는 일치를 ' }}} '닫는 문자열. 그러나 이는 일치 문자열에 '}'이 전혀 포함되지 않은 경우에만 작동합니다. 뭔가 같이 :

{{{cannot match {this broken} example}}} 

작동하지 않습니다하지만

{{{can match this example}}} 

이 작업을 수행합니다. 물론

항상 작동하지만 욕심이 많으므로 같은 줄에 여러 패턴이있는 경우에는 적합하지 않습니다.

나는 [^a]가 작동을 표시에도 불구하고, 나는 [^}}}] 3 개 연속 된 문자의 순서를 제외하는 올바른 방법이라고 생각하지 않는다, a 정도 b 제외하고는 아무 의미하는 a[^ab] 제외하고는 아무 의미하는 이해합니다.

그래서 어떻게 두 개의 다른 문자열로 구분 된 문자열과 일치하는 SED 용 정규식을 작성합니까?

답변

1

[^}}}]이 맞지 않습니다. 부정 문자 클래스는 그 안에있는 문자 중 하나가 아닌 문자와 일치합니다. 반복되는 문자는 논리를 변경하지 않습니다. 그래서 당신이 쓴 것은 [^}]과 같습니다. (표현식 안에 중괄호가 없을 때 이것이 왜 효과가 있는지 쉽게 알 수 있습니다.)

펄 호환 정규 표현식에서, 당신은 할 ?를 사용할 수있는 * 또는 + 비 욕심 :

s:{{{(.*?)}}}:$1:g 

이 항상 개방 {{{ 후 첫 }}} 일치합니다.

그러나, this is not possible in Sed. 사실, 나는 Sed에게이 경기를하는 어떤 방법도 없다고 생각합니다. 이것을 수행하는 다른 방법은 Sed가 가지고 있지 않은 look-ahead와 같은 고급 기능을 사용하는 것뿐입니다.

당신은 쉽게 각 라인을 통해 하나의 명령 줄에서 코드의 라인 (-e) 자동 루프를 수행하고 결과를 인쇄하는 원인이 -pe 옵션으로 나오지도 같은 방식으로 펄을 사용할 수 있습니다 (-p) .

perl -pe 's:{{{(.*?)}}}:$1:g' 

파일의 내부 편집에 대한 -i 옵션은 유용하지만, 정규식 먼저 올바른지 확인!

자세한 내용은 perlrun을 참조하십시오. 하지만, 오른쪽에서 교체하여

can match this example can match this 2nd example 

그것은 게으른 일치되지 않습니다 :와

sed -e :a -e 's/\(.*\){{{\(.*\)}}}/\1\2/ ; ta' 

:

{{{can match this example}}} {{{can match this 2nd example}}} 

이 제공

+0

답장을 보내 주셔서 감사합니다. 제가 생각하기에 sed가 앞을 내다 볼 수 없다는 것을 알았 기 때문입니다. 나는 당신의 예제에서 캡쳐 그룹을 탈출 할 필요가 없다는 것을 발견했다 :'{{{{. *?}}} : $ 1 <: g'' (실제로, 내가했을 때, t 일). – starfry

+0

@starfry, 죄송합니다, 당신은 캡처 그룹에 대한 권리입니다. 그것은 오타였습니다. –

0

sed하면 같은 뭔가를 할 수 왼쪽으로 우리는 sed의 욕심을 사용할 수 있습니다.

관련 문제