vim 정규식 질문

chsm2002의 이미지

vim의 강력한 치환 기능을 사용해서
<와 > 사이에 #이 두개 이상 나오면 첫번째 # 이외의 #은 _로 치환 을 하고싶습니다.

예를 들어
“<“http://simile.mit.edu/2006/01/entity#National_Association_of_Women_in_Construction-Greater_Phoenix,_Arizona_Chapter_#98.”>”

“<“http://simile.mit.edu/2006/01/entity#National_Association_of_Women_in_Construction-Greater_Phoenix,_Arizona_Chapter__98.”>”

“<“http://simile.mit.edu/2006/01/entity#Symposium_on_Nonlinear_Elasticity,_#c_University_of_Wisconsin-Madison_(1973).”> “

“<“http://simile.mit.edu/2006/01/entity#Symposium_on_Nonlinear_Elasticity,__c_University_of_Wisconsin-Madison_(1973).”> “
로..

정규식을 제대로 못써서 지금은 일일이 찾아서 고치고있습니다..

파일이 너무 커서 정말 난감하네요 도움 부탁드립니다.

jick의 이미지

s/\(<[^#>]*#[^#>]*\)#\(.*>\)/\1_\2/

이렇게 하면 안될까요? (문제는 두번째 #만 고친다는 건데, 더 이상 고쳐지는 줄이 없을 때까지 여러 번 돌리면-_- 될 것 같습니다.)

한번에 두번째/세번째 등등의 #를 다 날리는 건 lookbehind assertion을 쓰면 될 것 같기는 한데... 음 좀 어려울 것 같네요.

raymundo의 이미지

이것도 은근히 어렵네요... "두번째부터"라는 조건과 "부등호 사이의" 조건이 합쳐지니...

제대로 하려면 스크립트를 하나 짜는게 나을 것 같고, 에디터로 얼른 하려면 더 고민하느니 jick님 생각처럼 두번째 #만 고치는 걸 써서, 더 이상 치환이 안 될 때까지 반복하는 게 결과는 더 빨리 나올 것 같애요.

1,$s/\(<[^#>]*#[^#>]*\)#\(.\{-\}>\)/\1_\2/g

jick님 것에서 # 뒷부분을 .*에서 .\{-\}로 최소매치되도록 고친 겁니다. 한 라인에 부등호쌍이 두 번 이상 나올 수가 있는터라.

좋은 하루 되세요!

newyorker의 이미지

좀 수준이 떨어지긴 하지만... 일시적인 작업이라면 매크로를 통해 치환 작업을 만들고 <, > 개수만큼 반복 실행해주기만 하면 되잖아요.

asitgoes의 이미지

이미 해결하셨을거라 생각하지만...
제 경우에는 처음 #을 다른 문자나 문자열('@', 'REPLACE_BACK')로 치환 한 뒤에 다른 #들을 없애고 다시 처음에 치환한걸 원래대로 돌려주는 방법을 주로 씁니다..

----------------------------
어떻게든 되겠지..

raymundo의 이미지

"#"이 부등호쌍 안에만 있으면 말씀하신대로 되는데...
- 부등호쌍 내의 첫번째 #만 특정한 문자열로 바꿈
- 모든 #을 _로 바꿈
- 특정한 문자열을 다시 #으로 바꿈
위 세 가지는 각각 vim치환으로 한번에 끝낼 수 있으니까, 총 세 번 명령을 내려서 해결할 수 있겠죠.

그런데 부등호쌍 내부가 아닌 부분에 #이 있으면 그건 남겨야 하는데... 여기서 문제가 될 것 같습니다. 그런 #이 있는지 없는지는 본문 쓰신 분이 아시겠지만...

좋은 하루 되세요!

cleansugar의 이미지

무식한 저는 기계의 도움을 받고 있습니다.
http://kldp.org/node/107799

재벌 2세가 재벌이 될 확률과
금메달리스트 2세가 금메달을 딸 확률이 비슷해지도록
자유오픈소스 대안화폐를 씁시다.

아이디의 아이디어 무한도전
http://blog.aaidee.com

귀태닷컴
http://www.gwitae.com