次のファイルがあります。
<?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
Unicodeの値に置き換えたいのですが、すべてではなくstring
タグの1つに変更したいです。
別の正規表現を使用していくつかを実行しましたが、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>
私の問題は、私も交換することです空のスペースそして最初の文字2番目の単語のうち。私との経験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