Java 使用scanner.next()返回下一个n个字符

Java 使用scanner.next()返回下一个n个字符,java,regex,java.util.scanner,Java,Regex,Java.util.scanner,我正试图使用扫描仪来解析一些文本,但我一直得到一个InputMissmatchException。我正在使用scanner.next(Pattern Pattern)方法,我想返回下n个字符(包括空格) 例如,当试图解析出 "21 SPAN 1101" 我想在一个变量中存储前4个字符(“21”),然后在另一个变量中存储下6个字符(”),然后存储下5个字符(“SPAN”),最后存储最后4个字符(“1101”) 到目前为止,我得到的是: String input = "21

我正试图使用扫描仪来解析一些文本,但我一直得到一个InputMissmatchException。我正在使用scanner.next(Pattern Pattern)方法,我想返回下n个字符(包括空格)

例如,当试图解析出

"21        SPAN 1101"
我想在一个变量中存储前4个字符(
“21”
),然后在另一个变量中存储下6个字符(
),然后存储下5个字符(
“SPAN”
),最后存储最后4个字符(
“1101”

到目前为止,我得到的是:

String input =  "21        SPAN 1101";
Scanner parser = new Scanner(input);
avl = parser.next(".{4}");
cnt = parser.next(".{6}");
abbr = parser.next(".{5}");
num = parser.next(".{4}");
但是,即使根据扫描器的Java8文档,它仍然会抛出InputMismatchException。即使我显式声明该模式,然后将该模式传递到方法中,也会引发相同的异常

我是否完全用错误的类/方法处理这个问题?据我所知,我的语法是正确的,但我仍然不明白我为什么会出现这种异常。

在的文档中,我们可以找到它(强调我的)

如果下一个标记与由指定字符串构造的模式匹配,则返回下一个标记

<> >代码>扫描器< /C> >作为默认分隔符使用一个或多个空白,因此不考虑空间作为令牌的一部分。因此,它返回的第一个标记是
“21”
,而不是
“21”
,因此
{4}
的条件“…如果它与从指定字符串构造的模式匹配”,由于其长度,因此不满足

最简单的解决方案是使用
nextLine()
读取整行代码,并通过类似于
(.{4})(.{6})(.{5})(.{4})
或一系列子字符串方法的正则表达式将其拆分为单独的部分。

如果下一个标记与由指定字符串构造的模式匹配,则返回下一个标记

<> >代码>扫描器< /C> >作为默认分隔符使用一个或多个空白,因此不考虑空间作为令牌的一部分。因此,它返回的第一个标记是
“21”
,而不是
“21”
,因此
{4}
的条件“…如果它与从指定字符串构造的模式匹配”,由于其长度,因此不满足


最简单的解决方法是用<代码> NestRetro()/代码>读取整行,并通过正则表达式>代码> >({ 4 })(.{ 6 })(.{ 5 })({ 4 })< /代码>或子串方法系列,将其拆分为单独的部分。使用

Scanner.next()
的方法似乎失败了,因为没有将空格视为令牌的一部分(默认情况下,空格用作分隔符)。这样,您可以将输入字符串的结果片段存储在数组中,并将数组的特定元素分配给其他变量(我在注释中对适当的行做了一些额外的解释):


您可能想考虑创建一个方便的方法来将输入字符串切割成可变长度的可变长度,如<>代码>扫描器.NEXT()/<代码>似乎失败,因为不考虑空格作为令牌的一部分(默认情况下,空格用作分隔符)。这样,您可以将输入字符串的结果片段存储在数组中,并将数组的特定元素分配给其他变量(我在注释中对适当的行做了一些额外的解释):


我从这个问题中得到了一些主要的XY问题。你为什么试图从你的输入中捕获看似任意数量的空格?@Pshemo你的评论绝对值得我回答。如果你知道你的长度,为什么不使用
input.substring(int-beginIndex,int-endIndex)
?我从这个问题中感受到一些主要的XY问题。你为什么试图从你的输入中捕获看似任意数量的空格?@Pshemo你的评论绝对值得我回答。如果你知道你的长度,为什么不使用
input.substring(int-beginIndex,int-endIndex)
public static void main(String[] args) throws IOException {
    String input =  "21        SPAN 1101";
    String[] result = cutIntoPieces(input, 4, 6, 5, 4);

    // You can assign elements of result to variables the following way:
    String avl = result[0];  // "21  " 
    String cnt = result[1];  // "      "
    String abbr = result[2]; // "SPAN "
    String num = result[3];  // "1101"

    // Here is an example how you can print whole array to console:
    System.out.println(Arrays.toString(result)); 
}

public static String[] cutIntoPieces(String input, int... howLongPiece) {
    String[] pieces = new String[howLongPiece.length]; // Here you store pieces of input String
    int startingIndex = 0;
    for (int i = 0; i < howLongPiece.length; i++) { // for each "length" passed as an argument...
        pieces[i] = input.substring(startingIndex, startingIndex + howLongPiece[i]); // store at the i-th index of pieces array a substring starting at startingIndex and ending "howLongPiece indexes later"
        startingIndex += howLongPiece[i]; // update value of startingIndex for next iterations
    }
    return pieces; // return array containing all pieces
}
[21  ,       , SPAN , 1101]