java.util.Scanner.useDelimiter()
和Scanner.skip()
之间有什么区别?例如,我将这些字符串格式化为:
String line1 = "0---20.000:\t\t \t12%";
String line2 = "0--20.000:\t 12%";
String line3 = "0-20.000: \t \t12%";
String error = "0-: \t\t12%";
我需要这个输出:
0
20.000
12
我应该使用一个Scanner和一个对所有三个String都有效的模式,我需要控制令牌是三个,否则抛出一个异常。
我可以使用两种扫描仪方法获得此输出吗?
我应该使用哪种正则表达式?
它必须对其他数字也有效。
编辑:那是我的尝试:package scanners;
import java.util.Scanner;
public class ScannerTry {
public static void main(String[] args) {
String line = "0--20.000: 12%";
Scanner scan = new Scanner(line);
scan.useDelimiter("[-*:*\t*%]*");
while (scan.hasNext()){
System.out.println(scan.next());
}
scan.close();
}
}
但输出是:
0
2
0
.
0
0
0
1
2
答案 0 :(得分:1)
以下是您指定的分隔符:
scan.useDelimiter("[-*:*\t*%]*");
方括号包含一个字符列表,使用它们表示“匹配此列表中的字符”。方括号外的*
表示“匹配其中一个字符的0次或多次出现。”
您一次获得一个字符的原因是,当您匹配0次或多次时,这意味着空字符串(长度为0的字符串)与分隔符模式匹配。由于输入文件中每2个字符之间有一个空字符串(它们之间没有字符,因此空字符串匹配),扫描程序会将每个字符视为自己的标记。因此,您要做的第一件事就是将最后*
更改为+
,这意味着“匹配一次或多次匹配”。现在一个空字符串将不匹配。
你的模式的第二个问题是方括号内的*
只是意味着星号是你匹配的字符之一; “0或更多”的含义不适用于方括号内。事实上,无论何时你有方括号,无论它们内部是什么,这个模式总是匹配一个字符。因此,任何您想要指定为重复的*
,+
或其他任何内容都需要在方括号之外。
如果您只是取出*
:
scan.useDelimiter("[-:\t%]+");
现在,这将匹配-
,:
,制表符和%
字符的任意序列。但是,它与空格不匹配,我在一些示例中看到了空格。所以你可能想在方括号内添加一个空格。或者你可以这样说:
scan.useDelimiter("[-:\\s%]+");
因为方括号内的\s
组合意味着匹配“任何空白字符”,其中包括空格,制表符和其他一些像换行符。 (但只有在你确实想要匹配换行符时才这样做。)
另一件事:你把-
放在方括号内是正确的。如果不这样做,它可能有不同的含义:
"[a-z]"
匹配a
到z
中的任何字符,并且它与连字符不匹配。但是:
"[a\\-z]"
匹配a
,z
或连字符。一些程序员(包括我),当我们想要一个连字符在字符集中时,即使没有必要,也会在连字符上使用这个反斜杠,以避免任何可能的混淆:
scan.useDelimiter("[\\-:\t%]+");