【问题标题】:How best to determine if a String contains only null characters?如何最好地确定一个字符串是否只包含空字符?
【发布时间】:2021-08-03 09:08:27
【问题描述】:

检查字符串是否仅包含空字符的正确方法是什么?

String s = "\u0000";
if(s.charAt(0) == 0) {
   System.out.println("null characters only");
}

或者

String s = "\0\0";
for(int i = 0; i < s.length(); i++) {
   if(s.charAt(i) == 0) 
       continue;

   else break;

}

两者都有效。但是有没有更好更简洁的方法来执行这个检查。是否有一个实用程序来检查 java 中的字符串是否只包含 null 字符(\u0000\0)?

'\0''\u0000' 有什么区别?

【问题讨论】:

  • 嗯。我很难想到一个 valid 用例,它涉及测试一个字符串是否只包含 NUL 字符。 (我能想到的唯一用例是将非文本数据视为文本......这在概念上是错误的。)
  • @StephenC,我的服务需要调用下游服务器,它在json正文中返回一个参数说“eCode”,基于此我需要检查下游服务器是否有问题,所以如果此字符串为空或仅包含空字符,则一切正常,否则,如果“eCode”包含除我需要之外的任何其他内容,则向上游返回错误响应。
  • OK ... 那么为什么服务器会在 JSON 响应中向您发送一个包含 NUL 字符的字符串?那是……嗯……糟糕的设计。你确定你没有误解规范吗? (它可能实际上是说“一个空字符串或 null”?JSON 中有一个 null 值。)
  • 不,我什至测试过调用服务,他们返回空字符串,我最初认为它应该是空字符串或“”空字符串,但是当我的测试用例失败时,我意识到他们正在返回别的东西,这确实是一个糟糕的设计,我同意,但你知道,我必须处理它,因为我没有其他服务的所有权。

标签: java string java-8 char null-character


【解决方案1】:

char 文字(在 Java 中)可以用多种方式编写(所有这些方式都是等价的)。例如,

System.out.println('\u0000' == '\0');
System.out.println('\u0000' == 0);

会输出

true
true

因为char 是 Java 中的 16 位整数类型。而\u0000\00 这三个都是相同的值。至于查找 String 是否仅包含 0 char 值 - 只需迭代它。喜欢,

boolean allNulls = true;
for (int i = 0; i < s.length(); i++) {
    if (s.charAt(i) != 0) {
        allNulls = false;
        break;
    }
}

【讨论】:

  • ...如果你想要一个简洁的方式来做测试,把上面的代码放到一个方法/函数中。
  • @tusharRawat “util”是什么意思?您使用的任何内容都会在某个时刻循环遍历字符串的每个字符。只是您可能看不到您编写的代码中的循环。毕竟,如果不检查每个字符,你怎么知道 每个 字符是否为 NUL?
  • @tusharRawat 在这种情况下,我将参考 Stephen C 对您的问题的评论 - 这根本不是一件常见的事情(您也可能应该'根本不会这样做)。没有理由存在这样的实用程序。我的回答或 user15793316 的回答可能是你能得到的最短的解决方案。
  • @Sweeper 这不是更好(因为它会创建临时文件)但if (s.replaceAll("\u0000", "").length() == 0) { /* */ } 更短。至少我认为是。
  • @ElliottFrisch 为什么开发者经常想出创意的弯路却没有直接使用表达意图的方法?当您想检查字符串是否匹配某个模式时,只需使用,例如s.matches("\0*"),而不是用空字符串替换匹配项(replaceAll 也使用正则表达式引擎),只是为了测试是否只保留空字符串。如果您担心临时对象,请使用Pattern.compile(...) 重用构造真正昂贵的部分(Matcher 可以忽略不计)。
【解决方案2】:

您可以将chars() 获取为IntStream,然后使用allMatch

if (yourString.chars().allMatch(x -> x == 0)) {
    // all null chars!
}

【讨论】:

    【解决方案3】:

    您可以使用现有的 String 方法,例如 trimisEmpty 与此组合。 考虑一下:

    String s = "\u0000";
    s.trim().isBlank()
    

    【讨论】:

    • 但这也适用于\t\r 和其他全空白输入。
    • 是的,我没有考虑过。
    • 当您在代码示例中使用isBlank() 时,首先执行trim() 是没有意义的。 trim() 仅在您使用 isEmpty() 时才需要,如您回答的第一句话所述。
    【解决方案4】:

    \u0000 为 Unicode 值,控制台输出为空格

    Stream.of("\u0000","\0\0","jack", "luca")
      .filter(s -> !s.trim().equals(""))
      .forEach(System.out::println);
    

    输出:

    jack
    luca
    

    【讨论】:

    • 这是不正确的,因为它还会为某些包含非 NUL 字符的字符串打印 true
    • \u0000 的控制台输出取决于特定的控制台。
    【解决方案5】:

    你可以使用正则表达式

    匹配一个或多个\u0000

    boolean onlyNulls = string.matches("\u0000+");  // or "\0+"
    

    使用* 代替+ 也可以匹配空字符串


    (Sweeper 的流 solution 是我的首选解决方案 - 恕我直言,它更类似于预期的任务,尽管我会使用 '\u0000' 而不是 0

    【讨论】:

      【解决方案6】:

      我认为没有预定义的方法来检查它,我认为你提到的第二种方法是正确的测试方法

      【讨论】:

        猜你喜欢
        • 2015-09-28
        • 1970-01-01
        • 2018-11-27
        • 1970-01-01
        • 2013-11-26
        • 1970-01-01
        • 1970-01-01
        • 2011-02-24
        • 2012-01-05
        相关资源
        最近更新 更多