【问题标题】:Java Scanner ignores first token if it is empty如果第一个令牌为空,Java Scanner 将忽略它
【发布时间】:2018-06-11 20:15:57
【问题描述】:

我正在尝试使用扫描仪读取字符串标记的 InputStream。每个令牌都以逗号 , 结尾。空字符串"" 也是有效令牌。在这种情况下,整个标记只是结束它的逗号。

InputStream 是从另一个进程缓慢读取的,任何令牌都应在完全读取后立即处理。因此,将整个 InputStream 读取到 String 是不可能的。

示例输入可能如下所示:

ab,,cde,fg,

如果我将 Scanner 的分隔符设置为逗号,它似乎可以很好地处理这项工作。

InputStream input = slowlyArrivingStreamWithValues("ab,,cde,fg,");

Scanner scan = new Scanner(input);
scan.useDelimiter(Pattern.quote(","));
while (scan.hasNext()) {
    System.out.println(scan.next());
}

输出:

ab

cde
fg

但是,当流以空标记开始时,就会出现问题。出于某种原因,如果第一个令牌为空,则 Scanner 会忽略它。

/* begins with empty token */
InputStream input = slowlyArrivingStreamWithValues(",ab,,cde,fg,");
...

输出:

ab

cde
fg

为什么 Scanner 会忽略第一个令牌?我怎样才能包含它?

【问题讨论】:

标签: java java.util.scanner


【解决方案1】:

如果你自己写,不使用Scanner,会更容易:

static List<String> getValues(String source){
    List<String> list = new ArrayList<String>();
    for(int i = 0; i < source.length();i++){
        String s = "";
        while(source.charAt(i) != ','){
            s+=source.charAt(i++);
            if(i >= source.length()) break;
        }
        list.add(s);
    }
    return list;
}

例如,如果source = ",a,,b,,c,d,e",则输出将为"", "a", "", "c", "d", "e"

【讨论】:

  • OP 使用的是流,而不是固定字符串,q.v。我回答下的 cmets。
  • 我在发布答案后立即看到了 cmets。无论如何,一旦有字符串缓冲区,就可以使用字符串操作,所以我建议先做一个,然后再做。
  • 只是在逗号上使用String#split() 已经可以为 OP 提供所需的行为。
  • 如果字符串迭代替换为输入流迭代,则可能使用此方法。
【解决方案2】:

尝试使用后向作为模式:

(?<=,)

然后将逗号替换为您匹配的每个标记的空字符串。考虑以下代码:

String input = ",ab,,cde,fg,";
Scanner scan = new Scanner(input);
scan.useDelimiter("(?<=,)");
while (scan.hasNext()) {
    System.out.println(scan.next().replaceAll(",", ""));
}

这会输出以下内容:

(empty line)
ab

cde
fg

Demo

【讨论】:

  • 在这种情况下,输入是一个 InputStream,所以字符串操作是不可能的。
  • 如果你能读到内存,我可能会留下这个答案。
  • 这也是不可能的,因为令牌正在慢慢地来自另一个进程,并且应该在它们到来时立即处理。也许我应该编辑这个问题。
  • @Tuupertunut 以积极的方式进行标记似乎很有希望,q.v。我更新的答案。
  • @Tuupertunut 顺便说一句,我可能引入了另一个问题。现在,可能无法捕获尾随(即最终)逗号。但也许你不在乎。
猜你喜欢
  • 1970-01-01
  • 2013-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-07
相关资源
最近更新 更多