2017-01-15 2 views
0

У меня есть строка, которая содержит несколько символов в Юникоде. Я хочу идентифицировать все эти символы Юникода, например: \ uF06C, и заменить его на обратную косую черту и четыре шестнадцатеричные цифры без «u».Java Replace Unicode Characters в строке

Пример:

Источник Строка: "добавить \ uF06Cd1 Clause"

Строка результата: "добавить \ F06Cd1 Clause"

Как можно достичь этого в Java?

Edit:

Вопрос в связи Java Regex - How to replace a pattern or how to отличается от этого, как мой вопрос касается Юникода характера. Хотя он имеет несколько литералов, он рассматривается как один символ jvm, и поэтому регулярное выражение не будет работать.

+3

Возможный дубликат [Java Regex - Как заменить шаблон или как] (http://stackoverflow.com/questions/9285231/java-regex-how-to-replace-a-pattern-or-how- to) – Paul

+0

Вопрос по ссылке Java Regex - Как заменить шаблон или как отличается от этого, поскольку мой вопрос касается символа Unicode. Хотя он имеет несколько литералов, он рассматривается как один символ jvm, и поэтому регулярное выражение не будет работать. – Maz

ответ

0

Правильный способ сделать это - использовать регулярное выражение для соответствия всему определению юникода и использовать замену группы.

Регулярное выражение для соответствия строки юникода:

Юникода символов выглядит \uABCD, так \u, а затем HexNumber строкой 4 символов. Сопоставление это может быть сделано с помощью

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

Но есть проблема с этим:
В String как «только некоторые \\ uabcd произвольный текст» \u все равно пришлось бы соответствовать. Таким образом, мы должны убедиться, что \u будет предваряться четным числом \ с:

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

Теперь как выход, мы хотим, чтобы обратная косая черта, за которой следует hexnum-части. Это может быть сделано с помощью групповой замены, так что давайте начнем с группировкой символов:

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

В качестве замены мы хотим все люфты из группы, которая соответствует два обратных слеша, а затем с помощью обратной косой черты и hexnum-часть юникод-литерала:

$1\\$3 

Теперь для фактического кода:

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

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

Это много обратных косых черт! Ну, есть проблема с java, регулярным выражением и обратным слэшем: обратные слэши должны быть экранированы в java и regex. Таким образом, «\\\\» как строка шаблона в java соответствует одному символу, соответствующему регулярному выражению.

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-character» довольно неопределенно, поскольку char в java всегда представляет символы Unicode. Этот подход сохраняет любые контрольные символы, такие как «\ n», «\ r» и т. Д., Поэтому я выбрал его по другим определениям.

+0

попробовал это. Это дает мне результат такой же, как источник. – Maz

+0

@Maz вы запустили его в исходном коде или в строке-литерале? Если вы запустите его непосредственно в строке, вам придется прибегнуть к другому подходу. Этот ответ должен фильтровать исходный код, а не фактическую строку. – Paul

+0

Не совсем понял, что такое исходный код. Для этого я создал отдельный класс. Я определяю строковый литерал, который имеет ** добавить d1 Clause **, например 'String s =" add \ uF06Cd1 Clause ";', а затем использовать 4 строки кода из вашего комментария. Результат такой же, как строковый литерал. – Maz

-1

Попробуйте использовать метод String.replaceAll()

s = s.replaceAll ("\ и", "\");

+0

Ну, это будет работать большую часть времени. Но как насчет какой-то строки типа «... \\ u ....». Это не символ юникода, но ваш код будет с радостью переопределять его. Это определенно небезопасно использовать, так как рано или поздно он сломается. – Paul

+0

Это дает ошибки компиляции. При ускорении \ это не дает желаемого результата. – Maz

Смежные вопросы