如何在使用 Scanner 读取输入文件时跳过几个字符?

How can I skip a few characters while reading an input file with Scanner?

如何在使用 Scanner 读取输入文件时跳过几个字符? 我有这个输入文件,它在实际字符串之前有一些数字,我不能删除这些数字,因为它们也很重要。我需要将它们存储在另一个整数数组中:

3 onion pepper olive
3 mushroom tomato basil
3 chicken mushroom pepper
3 tomato mushroom basil
2 chicken basil

我可以跳过整数并先读取字符串,然后再读取整数吗? 这是我一直在处理的所有代码:

        import java.util.*;
        import java.io.*;
        public  class Pizza {
            public static int numofpizzas;
            public static Scanner input;
            public static String[][] pizzaIng;
            public static File file;
            public static void main(String[] args) throws FileNotFoundException {
                // assigning the file object
                file = new File("an example");
                // setting up the scanner
                input = new Scanner(file);
                // reading and storing the input file data
                pizzaIng = new String[][]{{input.nextLine()},{input.nextLine()},{input.nextLine()} 
                {input.nextLine()},{input.nextLine()},{input.nextLine()}};
                for (String[] i: pizzaIng) {
                    for (String j: i) {
                        System.out.println(j);
                    }
                }
            }

        }

这有几种方法,但这完全取决于数据。这里有两种可能的方法,

  1. 获取仅包含项目名称的新子字符串。

如果你的例子中提到的模式是一致的,并且数量总是小于10,那么项目名称的起始索引是固定的,你可以使用这种方法。因此,在代码片段的最后一个 for 循环中,您可以执行以下操作,

for (String j: i) {
    int startingIndex = 2
    j = j.substring(startingIndex)
}

然而,缺点是如果数量超过 9 个或更多,则起始索引会更改,结果您的子字符串将丢失第一个字符。

  1. 使用正则表达式替换(删除)数字字符。

在这种情况下,即使数量超过一位数(10 个或更多),数字也会被删除并保留商品。

for (String j: i) {
    String pattern = "[0-9]"
    j = j.replaceAll(pattern, "")
}

但是,如果项目名称包含数字,那么它们也会被替换。这就是这种方法的缺点。为了克服这个问题,可以使用以下正则表达式,其中正则表达式仅

for (String j: i) {
    String pattern = "([0-9]+)([A-Za-z\s0-9]+)"
    j = j.replaceAll(pattern, "")
}

此正则表达式将部分字符串分解为两部分:由“([0-9]+)”表示的数量和由“([A-Za-z\s0-9]+)”表示的项目名称,其中我们项目名称接受字母数字和空格。然后在下一行中,整个字符串被替换为“$2”,其中“$2”表示项目名称。所以只保留项目名称(可能包括数字)。字符串的数量部分被删除。

希望这对您有所帮助 :) 如果有帮助,请将我的回答标记为“已接受”,我将不胜感激。美好的一天!

您可以使用 subString() 方法跳过字符串的第一个字符。使用 .subString(1) 只会跳过字符串的第一个字符(在您的情况下是整数),而 .subString(2) 将跳过前两个字符(在您的情况下是整数和 space)。

新代码如下所示:

import java.util.*;
import java.io.*;
public  class Pizza {
    public static int numofpizzas;
    public static Scanner input;
    public static String[][] pizzaIng;
    public static File file;
    public static void main(String[] args) throws FileNotFoundException {
        // assigning the file object
        File file = new File("testText.txt");
        // setting up the scanner
        input = new Scanner(file);
        // reading and storing the input file data
        pizzaIng = new String[][]{{input.nextLine()},{input.nextLine()},{input.nextLine()},
                {input.nextLine()},{input.nextLine()}};

        for (String[] i: pizzaIng) {
            for (String j: i) {
                System.out.println(j.substring(2));
            }
        }
    }
}

既然“前面的数字也很重要”,为什么不在整行开头创建一个class呢?

class Ingredient {
 // add getters and setters for those
 int amount;
 String name;
}

然后您可以为每一行创建其中一种成分。既然这是你原来的问题,也许你可以使用

static Pattern ingredientPattern = Pattern.compile("([0-9]+) (.*)");
public static Ingredient fromLine(String line) {
 Ingredient result = new Ingredient();
 Matcher matcher = ingredientPattern.matcher(line);
 if (matcher.matches()) {
  result.setAmount(Integer.parseInt(matcher.group(1)));
  result.setName(Integer.parseInt(matcher.group(2)));
 } // else throw exception or something
 return result;
}

该模式是一个包含两组的正则表达式,第一组包含数字([0-9]+,+ 表示“1 或更多”),第二组包含字符串的其余部分。

你应该能够用

解析整个事情
List<Ingredient> ingredients = new ArrayList<>();
Scanner sc = new Scanner(input);
while(sc.hasNext()) {
 ingredients.add(fromLine(sc.nextLine()));
}

或者,对于给定的文件名

List<Ingredient> ingredients = 
 Files.lines(filename)
  .map(MyClass::fromLine)
  .collect(Collectors.toList());