다음 파일이 있습니다.
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.net-->
<string name="test" >- test</string>
<string name="test" >test-test</string>
<string name="test" >test - test</string>
en dash
유니코드 값으로 바꾸고 싶지만 전부는 아니고 string
태그 중 하나로 바꾸고 싶습니다.
다른 정규식을 사용하여 몇 가지를 실행했지만 sed
알아낼 수 없습니다. 그 중 하나는
sed -i.bak "s/-[^-\<\>0-9]/\–\;/g" strings.xml
출력은 다음과 같습니다
<?xml version="1.0" encoding="utf-8"?>
<!-–enerated by-->
<string name="test" >–test</string>
<string name="test2" >test–est</string>
<string name="test3" >test –test</string>
내 문제는 나도 교체한다는 것입니다빈 공간그리고첫 번째 문자두 번째 단어 중. 나는 regex
및 에 대한 경험이 많지 않습니다 sed
. 내가 뭘 잘못하고 있는지 설명해 주실 수 있나요?
참고: 저는 OSX를 사용하고 있습니다.
답변1
가장 가까운 (for \K
및 s///r
) 를 사용 perl
하고 <string>
태그가 중첩되지 않았다고 가정합니다.
perl -0777 -pi.bak -e's{<string.*?>\K.*?(?=</string>)}{$&=~s/-/–/rg}ges' file.xml
-0777
:흡연 모드<string>
: 전체 파일을 한 번에 처리합니다( 태그가 여러 줄에 걸쳐 표시되도록 허용 ).-p
:sed
모델-i.bak
: 확장 기능을 사용한 내부 편집.bak
(btw, 여기에서sed
일부 구현에 대한 아이디어가 나왔습니다)s{...}{...}ges
: 전역 대체(g
). 개행.
문자(s
)와도 일치하며 대체를perl
실행할 코드(e
)로 처리합니다.<string.*?>\K.*?</string>
: is 부분에 태그 자체를 포함하지 않고 from<string...>
to와 일치합니다.</string>
일치(\K
정의하는일치섹션이 시작되고(?=...)
미리보기 연산자입니다.조사하다존재 하지만</string>
일치 항목에 포함되지 않음).$&=~s/.../.../rg
. 대체하세요일치부분($&
). 이r
플래그는 실제로 수정되지는 않지만$&
대체된 문자열을 반환합니다.
답변2
휴, 시간이 지나서야 깨달았습니다. 이것은 순진한 해결책입니다.테든의 답변더 정확하게 말하면 그의 :)를 사용해야 합니다.
sed -Ei.bak "s/(.*<string[^>]*\")(.*)-(.*)/\1\2\–\3/g" strings.xml
나는 사용하고있다역참조이전에 일치된 문자열에 대한 참조입니다. 이것들이 다 \1
\2
기다리고 있어
이 경우 sed는 다음 그룹과 일치해야 합니다.
(.*<string[^>]*\")
- 문자 뒤에 따옴표까지 문자열 토큰이 옵니다"
.그룹 1(.*)
- 그룹 3 이후"
(현재>
)까지의 모든 것.그룹 2-
일치하는 대시(.*)
- 대시 이후의 모든 것과 일치합니다.그룹 3
그런 다음 이전에 일치했던 그룹 및 대시 HTML 값으로 대체 –
하고 그룹에 대한 참조로 \n
사용 했습니다 .n
n
질문:
현재 몇 가지 문제를 해결하려고 노력하고 있으니 협조해 주시기 바랍니다.
- 그룹 1 대회도 마찬가지
dsfjpasj<string
- 그룹 1에는 문자열 표시 종료 문자가 포함되어야 합니다.
>
>1 -
terdon이 지적한 대로: "여러 줄에 걸쳐 있는 태그나 태그가 있거나 중첩된 경우에는 작동하지 않습니다."
더 읽어보세요:
http://toytoygogie.blogspot.de/2010/02/using-sed-with-backreference-as.html
답변3
-
내가 올바르게 이해했다면 태그 내의 모든 사례(예제에서는 3개) <strng></string>
와 해당 사례만 바꾸길 원할 것입니다 . 그렇다면 이 방법이 효과가 있을 것입니다.XML이 정상이라고 가정:
정규 표현식과 다음과 같은 간단한 도구를 사용하세요.
sed
sed 's/\(<string[^>]*>[^-]*\)-\([^-]*<\/string\)/\1\–\2/' file.xml
귀하의 파일이언제나위의 예와 같이 태그가 항상 임을 확신할 수 있습니다
<string name="test" ></string>
.검토:perl -pe 's/(?<=<string name="test" >)([^<]*?)-([^<]*)/$1–$2/g' file.xml
-
태그 내에 태그가 여러 개 있으면 위의 방법 중 어느 것도 작동하지 않습니다. 이 상황을 처리하기 위해 우리가<string></string>
태그 안에 있는지 확인하는 간단한 작은 스크립트를 작성할 수 있습니다 . 중첩된 태그도 처리해야 합니다.perl -F'<' -lane 'for($i=0;$i<=$#F;$i++){ $a++ if $F[$i]=~/^string/; $F[$i]=~s/-/–/g if $a>0; $a-- if $F[$i]=~/^\/string/ } print join "<",@F' file.xml