Regex & Sed/Perl: 다른 단어가 앞에 오지 않는 단어 일치

Regex & Sed/Perl: 다른 단어가 앞에 오지 않는 단어 일치

특정 단어가 앞에 나오지 않는 모든 단어를 사용 sed하거나 바꾸고 싶습니다 .perl

예를 들어, 영화의 줄거리가 포함된 텍스트 파일이 있고 모든 성을 캐릭터의 이름으로 바꾸고 싶습니다. 단, 이름이 성 바로 앞에 오지 않는 경우에만 해당됩니다.

샘플 텍스트는 다음과 같습니다.

John Smith and Jane Johnson talk about Smith's car.

나는 그것이 다음과 같이 보이기를 원합니다 :

John Smith and Jane Johnson talk about John's car.

이렇게 하면 다음 sed 's/Smith/John/' file과 같이 됩니다.

John John and Jane Johnson talk about John's car.

성 앞의 이름은 항상 동일합니다. 나는 John Smithand 를 다룰 필요가 없습니다 Frank Smith. Smith이전에 존재하지 않았던 매칭 방법이 필요합니다 .John

답변1

이는 정규식이 거꾸로 보일 수 있는 모든 언어에서 쉽습니다. 물론 Perl이 목록의 첫 번째입니다.

perl -pe 's/(?<!John\W)Smith/John/g' <<< "John Smith and Jane Johnson talk about Smith's car."

약점은 "John"과 "Smith" 사이에 단어가 아닌 문자가 여러 개 있다는 것입니다. 불행하게도 +for와 같은 수량자는 \W"가변 길이 역방향 조회가 구현되지 않음" 오류를 발생시킬 수 있습니다.

답변2

편집하다.. 귀하의 의견과 관련하여 .. 이것은 새로운 스크립트이며 (예를 들어) William Smith에는 관심이 없습니다. 유지하는 패턴을 일시적으로 난독화합니다.스미스(끊임없는).

sed -r 's/\<(John) (Smith)\>/\1\x01x\2/g; 
        s/\<Smith\>/John/g;  s/\x01x/ /g'

걱정된다면선생님, 부인...글쎄, 이것은 작동합니다.

sed -r 's/\<(John|((M(r|rs|s))\.?)) (Smith)\>/\1\x01x\5/g
        s/\<Smith\>/John/g; s/\x01x/ /g'

당신은 만족할 수 있습니다윌리엄그의 이름을 다음에 추가하세요또는예를 들어 목록을 작성하십시오.
sed -r 's/\<(William|John|...


원본 스크립트입니다

sed -r 's/(^|[[:punct:]] |\<[a-z]+ )(Smith\>)/\1John/'

답변3

 sed -r 's/([^John] )Smith/\1John/g;s/([^Jane] )Johnson/\1Jane/g'

()는 성 앞에 이름이 아닌 이름을 캡처하므로 대체 시 역참조됩니다.

편집하다

@manatwork, 자일스

네가 옳아. 어때요?

sed -r 's/(John Smith)/temp1/g;s/Smith/John/g;s/temp1/John Smith/g'

이것이 트릭을 수행하는 것 같습니다.

관련 정보