java - 如何在 Java 中用 Unicode 字符填充字符串

标签 java unicode text-formatting

我将右填充添加到 String 以表格格式输出它。

for (String[] tuple : testData) {
  System.out.format("%-32s -> %s\n", tuple[0], tuple[1]);
}
结果如下(随机测试数据):
znZfmOEQ0Gb68taaNU6HY21lvo       -> Xq2aGqLedQnTSXg6wmBNDVb
frKweMCH8Kvgyk0J                 -> lHJ5r7YDV0jTL
NxtHP                            -> odvPJklwIzZZ
NX2scXjl5dxWmer                  -> wPDlKCKllVKk
x2HKsSHCqDQ                      -> RMuWLZ2vaP9sOF0yHmjVysJ
b0hryXKd6b80xAI                  -> 05MHjvTOxlxq1bvQ8RGe
当存在多字节 unicode 字符时,此方法不起作用:
0OZot🇨🇳ivbyG🧷hZM1FI👡wNhn6r6cC -> OKDxDV1o2NMqXH3VvE7q3uONwEcY5V
fBHRCjU4K8OCdzACmQZSn6WO         -> gvGBtUO5a4gPMKj9BKqBHFKx1iO7
cDUh🇲🇺b0cXkLWkS                -> SZX
WtP9t                            -> Q0wWOeY3W66mM5rcQQYKpG
va4d🍷u8SS                       -> KI
a71?⚖TZ💣🧜‍♀🕓ws5J              -> b8A
如您所见,对齐已关闭。
我的想法是计算字符串的长度和使用的字节数之间的差异,并使用它来抵消填充,如下所示:
int correction = tuple[0].getBytes().length - tuple[0].length();
然后我不会填充到 32 个字符,而是填充到 32 + correction .然而,这也不起作用。
这是我的测试代码(使用 emoji-java 但该行为应该可以使用任何 unicode 字符重现):
import java.util.Collection;
import org.apache.commons.lang3.RandomStringUtils;
import com.vdurmont.emoji.Emoji;
import com.vdurmont.emoji.EmojiManager;

public class Test {

  public static void main(String[] args) {
    // create random test data
    String[][] testData = new String[15][2];
    for (String[] tuple : testData) {
      tuple[0] = RandomStringUtils.randomAlphanumeric(2, 32);
      tuple[1] = RandomStringUtils.randomAlphanumeric(2, 32);
    }

    // add some emojis
    Collection<Emoji> all = EmojiManager.getAll();
    for (String[] tuple : testData) {
      for (int i = 1; i < tuple[0].length(); i++) {
        if (Math.random() > 0.90) {
          Emoji emoji = all.stream().skip((int) (all.size() * Math.random())).findFirst().get();
          tuple[0] = tuple[0].substring(0, i - 1) + emoji.getUnicode() + tuple[0].substring(i + 1);
        }
      }
    }

    // output
    for (String[] tuple : testData) {
      System.out.format("%-32s -> %s\n", tuple[0], tuple[1]);
    }
  }
}

最佳答案

这里实际上存在一些问题,除了某些字体显示的标志比其他字符宽。我假设您想将中国国旗算作单个字符(因为它在屏幕上是作为单个元素绘制的)。
String 类报告错误的长度
String 类适用于 char s,它们是 Unicode 代码点的 16 位整数。问题是并非所有代码点都适合 16 位,只有来自基本多语言平面 (BMP) 的代码点适合这些 char s。 Stringlength()方法返回char的数量s,不是代码点的数量。
现在 StringcodePointCount在这种情况下,方法可能会有所帮助:它计算给定索引范围内的代码点数。所以提供string.length()作为该方法的第二个参数,返回代码点的总数。
组合字符
然而,还有另一个问题。例如,🇨🇳 中国国旗由两个 Unicode 代码点组成:区域指示符字母 C(🇨,U+1F1E8)和 N(🇳,U+1F1F3)。这两个代码点组合成一个中国国旗。这是您无法使用 codePointCount 解决的问题。方法。
区域指标符号字母 seem成为一个特殊的场合。其中两个字符可以组合成一面国旗。我不知道实现您想要的标准方法。您可能必须手动考虑这一点。
我编写了一个小程序来获取字符串的长度。

static int length(String str) {
    String a = "\uD83C\uDDE6";
    String z = "\uD83C\uDDFF";

    Pattern p = Pattern.compile("[" + a + "-" + z + "]{2}");
    Matcher m = p.matcher(str);
    int count = 0;
    while (m.find()) {
        count++;
    }
    return str.codePointCount(0, str.length()) - count;
}

关于java - 如何在 Java 中用 Unicode 字符填充字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64397528/

相关文章:

LaTeX - 描述列表 - 将项目拆分成多行

java - Weka Kernel Estimator 类中的带宽是如何计算的?

ruby - 解释那些转义数字在 ruby​​ 1.8.7 中的 unicode 编码中意味着什么

haskell - 为什么这个 Haskell 语句在 GHCi 中有效但无法编译?

PHP 正确的正则表达式在带有 unicode 的 PHP 5.3.3-7 中不起作用

emacs - 如何自动对齐不同代码段中的注释?

delphi - 如何使用 Delphi 中的当前区域设置格式化整数

java : The import collides with another import statement

java - Google Web Toolkit 转储所有请求和响应

java - 当我将鼠标放在 JLabel 上时如何调用 JFrame 以及当我从 JLabel 上移除鼠标时如何关闭相同的 JFrame?