2017-01-15 24 views
0

複数のUnicode文字を含む文字列があります。これらのユニコード文字をすべて特定したい場合は、¥uF06Cとし、"u"を含まないバックスラッシュと4桁の16進数に置き換えます。Java文字列のUnicode文字を置換する

ソース文字列:"\ uF06Cd1句を追加"

結果文字列:Javaでこれを実現するにはどうすればよい

を "\ F06Cd1句を追加しますか"?

編集:私の質問は、Unicode文字を扱うようリンクJava Regex - How to replace a pattern or how to

質問はこれと異なっています。それは複数のリテラルを持っていますが、それはjvmによって1つの文字としてみなされるため、正規表現は機能しません。

+3

[Java Regex - パターンを置き換える方法または方法](http://stackoverflow.com/questions/9285231/java-regex-how-to-replace-a-pattern-or-how- ) – Paul

+0

リンクの質問Java Regex - どのようにパターンを置き換えるか、または私の質問がユニコード文字を扱うようにこれとは異なる方法。それは複数のリテラルを持っていますが、それはjvmによって1つの文字としてみなされるため、正規表現は機能しません。 – Maz

答えて

0

これを行う正しい方法は、正規表現を使用してユニコード定義全体を照合し、グループ置換を使用することです。

ユニコード文字列にマッチする正規表現:

ユニコード文字は\uABCDのように見えるので、\u、4文字のhexnumber文字列が続きます。マッチングこれらは

\\u[A-Fa-f\d]{4} 

を使用して行うことができる。しかしこれに伴う問題があります:\uはまだマッチになるだろう「ほんの一部\\ uabcd任意のテキスト」などのString
が。だから我々は\u\秒の偶数が付け加えていることを確認する必要があります。

(?<!\\)(\\\\)*\\u[A-Fa-f\d]{4} 

今すぐ出力として、我々はhexnum部分が続くバックスラッシュをしたいです。これは、グループ交換によって行われ、その者が文字をグループ化することによって開始取得してみましょうすることができます。バックスラッシュとのhexnum部分に続いて、我々は2つのバックスラッシュにマッチするグループからすべてのバックラッシュをしたいの交換として

(?<!\\)(\\\\)*(\\u)([A-Fa-f\d]{4}) 

ユニコードリテラル:

String pattern = "(?<!\\\\)(\\\\\\\\)*(\\\\u)([A-Fa-f\\d]{4})"; 
String replace = "$1\\\\$3"; 

Matcher match = Pattern.compile(pattern).matcher(test); 
String result = match.replaceAll(replace); 

バックスラッシュがたくさんあります:実際のコードのために今

$1\\$3 

!さて、Java、正規表現、バックスラッシュには問題があります。バックスラッシュはjava 正規表現でエスケープする必要があります。したがって、javaのパターン文字列としての "\\\\"は、正規表現と一致する文字の1つと一致します。

EDIT:実際の文字列の
、文字が除外されるように、その整数の表現に置き換えることが必要です

StringBuilder sb = new StringBuilder(); 
for(char c : in.toCharArray()) 
    if(c > 127) 
     sb.append("\\").append(String.format("%04x", (int) c)); 
    else 
     sb.append(c); 

これは、あなたが非ASCII-文字を意味する「ユニコード文字」で想定しています。このコードは任意のASCII文字をそのまま出力し、他のすべての文字をバックスラッシュとUnicodeコードで出力します。 javaのcharは常にUnicode文字を表しているので、 "unicode-character"の定義はやや曖昧です。このアプローチでは、 "\ n"、 "\ r"などの制御文字をそのまま使用するため、他の定義よりも選択しています。

+0

もこれを試しました。それは私にソースと同じ結果を与えます。 – Maz

+0

@Mazはソースコードや文字列リテラルで実行しましたか?文字列上で直接実行する場合は、別の方法に頼らなければなりません。この答えは、実際の文字列ではなくソースコードをフィルタリングすることになっています。 – Paul

+0

ソースコードとは何か分かりませんでした。私はこれをテストするスタンドアロンのクラスを作成しました。 'String s =" add \ uF06Cd1 Clause ";'のように、** addd1句**を持つ文字列リテラルを定義し、あなたのコメントから4行のコードを使用します。結果は文字列リテラルと同じです。 – Maz

-1

S = s.replaceAll( "\ U"、 "\")String.replaceAll()メソッドを使用してみてください。

+0

さて、それはほとんどの時間で動作します。でも、 "... \\ u ...."のような文字列はどうですか?これはユニコード文字ではありませんが、コードはそれをうまく上書きします。遅かれ早かれ破綻するため、これは絶対に安全ではありません。 – Paul

+0

これはコンパイルエラーを出します。エスケープすると\、目的の結果は得られません。 – Maz

関連する問題