gpt4 book ai didi

java.util.Scanner 的 useDelimiter ("") 或 useDelimiter(Pattern.compile ("\\s")) 与标准行为不同

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:06:42 24 4
gpt4 key购买 nike

给出下面的代码,它输出:

Feed a chunk of data here:           
I have found: 0 words; 0 ints; 0 booleans;

如果我键入 10 个空格并保留两个 useDelimiter 方法调用的注释,则输出:

Feed a chunk of data here:           
I have found: 9 words; 0 ints; 0 booleans;
sssssssss

如果我键入完全相同的 10 个空格但确实使用了两个 useDelimiter 调用之一。为什么会这样?不应该一样吗?这是代码,谢谢:

package com.riccardofinazzi.regex;

import java.io.Console;
import java.util.Scanner;
import java.util.regex.Pattern;
import java.util.ArrayList;

class ScanNext {
public static void main(String[] args) {

/* match counters */
int hits_s = 0, hits_i = 0, hits_b = 0;

/* current token value */
String s;
Integer i;
Boolean b;

ArrayList<Object> al = new ArrayList<Object>();

Scanner s1 = new Scanner(System.console().readLine("Feed a chunk of data here: "));

/* not needed as this is def behaviour, I put it here to not forget the method */

//s1.useDelimiter(Pattern.compile("\\s"));
//s1.useDelimiter(" ");

while(s1.hasNext()) {
if ( s1.hasNextInt()) {
al.add(s1.nextInt()); hits_i++;

} else if ( s1.hasNextBoolean()) {
al.add(s1.nextBoolean()); hits_b++;

} else { al.add(s1.next()); hits_s++;
}
}

System.out.println("I have found:\t"+hits_s+" words; "+hits_i+" ints; "+hits_b+" booleans;");

for (Object in : al) {
if (in instanceof String)
System.out.print("s");
if (in instanceof Integer)
System.out.print("i");
if (in instanceof Boolean)
System.out.print("b");
}
System.out.print("\n");
}
}

最佳答案

假设 X 是定界符。

如果我们扫描像 "aXbXc" 这样的文本,很明显有 3 个标记:"a" "b"“c”

如果我们扫描像 "aXXc" 这样的文本,仍然有 3 个标记,但是这次:"a" ""“c”。这是因为我们将定界符设置为一次仅匹配一个 X,因此它不会将另一个 X 视为已匹配定界符的延续,而是作为单独的定界符。
(这在分隔符是 , 的情况下非常有用,我们扫描像 1,2,,,3 这样的数据,因为它应该代表元素: 1 2 无数据 无数据 3).
如果您希望定界符表示一个或多个 X,则需要使用 X+,因为 + 是表示“一次或多次”的量词。这样 aXXc 将仅表示 "a""c" 元素,因为整个 XX 将被视为一个元素分隔符。

另一个有趣的例子是aXbX。如您所见,此处没有 c文本以分隔符结尾。在这种情况下,Scanner 不会假设在最后一个定界符之后有空元素,因此它只会将 "a""b" 视为标记,而不是 "a ", "b", "".

同样适用于XbXc,其中文本以定界符开头。 Scanner 不假设在它之前有一些空元素。


现在让我们回到你的案例。

如果您打印 Scanner 的默认分隔符(使用类似 System.out.println(s1.delimiter()); 的代码),您将看到它是 \p{javaWhitespace}+。所以默认情况下,分隔符是一个或多个空格。但稍后您将其更改为单个 空格或空格族。这意味着对于字符串

"          "
  • 如果定界符是\p{javaWhitespace}+ 那么整个表达式匹配为一个定界符所以在定界符之前、之后和之间没有元素,所以有是 0 个标记(非分隔符元素)
  • 但是如果我们使用 """\\s" 作为分隔符,那么 Scanner 将找到 10 个分隔符(每个空格是 一个他们)。由于有 10 个分隔符,这意味着它们之间有 9 个元素(即使是空字符串也算在内)。文本也以定界符开始和结束,这意味着在第一个定界符之前或最后一个定界符之后没有标记。

关于java.util.Scanner 的 useDelimiter ("") 或 useDelimiter(Pattern.compile ("\\s")) 与标准行为不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43914981/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com