【问题标题】:Java Replace Unicode Characters in a StringJava 替换字符串中的 Unicode 字符
【发布时间】:2017-01-15 23:46:52
【问题描述】:

我有一个包含多个 unicode 字符的字符串。我想识别所有这些 un​​icode 字符,例如:\ uF06C,并将其替换为一个反斜杠和四个不含 "u" 的十六进制数字。

示例

源字符串:"add \uF06Cd1 Clause"

结果字符串:“添加\F06Cd1子句”

如何在 Java 中实现这一点?

编辑:

链接Java Regex - How to replace a pattern or how to 中的问题与此不同,因为我的问题涉及 unicode 字符。虽然它有多个文字,但它被 jvm 视为一个字符,因此正则表达式不起作用。

【问题讨论】:

  • 链接 Java 正则表达式中的问题 - 如何替换模式或如何与此不同,因为我的问题涉及 unicode 字符。虽然它有多个文字,但它被 jvm 视为一个字符,因此正则表达式不起作用。

标签: java unicode replace str-replace


【解决方案1】:

执行此操作的正确方法是使用正则表达式来匹配整个 unicode 定义并使用组替换。

匹配 unicode-string 的正则表达式:

一个 unicode 字符看起来像 \uABCD,所以是 \u,后跟一个 4 个字符的十六进制数字字符串。匹配这些可以使用

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

但是这样做有一个问题:
在像“只是一些 \\uabcd 任意文本”这样的 String 中,\u 仍然会匹配。所以我们需要确保\u前面有偶数个\s:

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

现在作为输出,我们需要一个反斜杠,后跟一个十六进制数字部分。这可以通过组替换来完成,所以让我们开始对字符进行分组:

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

作为替换,我们希望组中的所有反斜杠匹配两个反斜杠,后跟一个反斜杠和 unicode-literal 的十六进制部分:

$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、regex 和反斜杠存在一个问题:java regex 中需要对反斜杠进行转义。所以“\\\\”作为java中的模式字符串匹配一个\作为正则表达式匹配的字符。

编辑:
在实际的字符串中,字符需要被过滤掉并用它们的整数表示来替换:

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

这假设“unicode-character”是指非 ASCII 字符。此代码将按原样打印任何 ASCII 字符,并将所有其他字符输出为反斜杠,后跟其 unicode 代码。不过,“unicode-character”的定义相当模糊,因为 java 中的 char 总是代表 unicode-characters。这种方法保留了任何控制字符,如“\n”、“\r”等,这就是我选择它而不是其他定义的原因。

【讨论】:

  • 也试过了。它给了我与源相同的结果。
  • @Maz 你是在源代码还是字符串文字上运行它的?如果你直接在字符串上运行它,你将不得不求助于另一种方法。这个答案应该过滤源代码,而不是实际的字符串。
  • 不太明白什么是源代码。我创建了一个独立的类来测试这个。我定义了一个具有 add d1 子句 的字符串文字,例如String s = "add \uF06Cd1 Clause";,然后使用您评论中的 4 行代码。结果与字符串文字相同。
  • @Maz 在源代码中,字符串看起来像这样“\u202Eabc”。实际的String 将是“cba”(\u202E 是文本反转)。
  • @Maz 好吧。您想直接匹配字符串中的 unicode 字符并替换它们。这在一定的限制内是可行的。我会相应地更新我的答案
【解决方案2】:

尝试使用 String.replaceAll() 方法

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

【讨论】:

  • 嗯,大部分时间都可以。但是像“...\\u....”这样的字符串怎么样。这不是 unicode 字符,但您的代码会很高兴地覆盖它。这绝对不安全,因为它迟早会坏掉。
  • 这个给出了编译错误。在转义 \ 时,它不会给出想要的结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-20
  • 2014-12-03
  • 2013-06-25
  • 2015-12-23
  • 1970-01-01
  • 1970-01-01
  • 2013-07-09
相关资源
最近更新 更多