Java Scanner,模式和useDelimiter()和skip()之间的区别

时间:2017-06-04 23:25:21

标签: java regex java.util.scanner delimiter

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

1 个答案:

答案 0 :(得分:1)

以下是您指定的分隔符:

scan.useDelimiter("[-*:*\t*%]*");

方括号包含一个字符列表,使用它们表示“匹配此列表中的字符”。方括号外的* 表示“匹配其中一个字符的0次或多次出现。”

您一次获得一个字符的原因是,当您匹配0次或多次时,这意味着空字符串(长度为0的字符串)与分隔符模式匹配。由于输入文件中每2个字符之间有一个空字符串(它们之间没有字符,因此空字符串匹配),扫描程序会将每个字符视为自己的标记。因此,您要做的第一件事就是将最后*更改为+,这意味着“匹配一次或多次匹配”。现在一个空字符串将不匹配。

你的模式的第二个问题是方括号内的*只是意味着星号是你匹配的字符之一; “0或更多”的含义不适用于方括号内。事实上,无论何时你有方括号,无论它们内部是什么,这个模式总是匹配一个字符。因此,任何您想要指定为重复的*+或其他任何内容都需要在方括号之外。

如果您只是取出*

scan.useDelimiter("[-:\t%]+");

现在,这将匹配-:,制表符和%字符的任意序列。但是,它与空格不匹配,我在一些示例中看到了空格。所以你可能想在方括号内添加一个空格。或者你可以这样说:

scan.useDelimiter("[-:\\s%]+");

因为方括号内的\s组合意味着匹配“任何空白字符”,其中包括空格,制表符和其他一些像换行符。 (但只有在你确实想要匹配换行符时才这样做。)

另一件事:你把-放在方括号内是正确的。如果不这样做,它可能有不同的含义:

"[a-z]"

匹配az中的任何字符,并且它与连字符不匹配。但是:

"[a\\-z]"

匹配az或连字符。一些程序员(包括我),当我们想要一个连字符在字符集中时,即使没有必要,也会在连字符上使用这个反斜杠,以避免任何可能的混淆:

scan.useDelimiter("[\\-:\t%]+");