提问人:KidsSeeKanye 提问时间:11/14/2022 最后编辑:Hovercraft Full Of EelsKidsSeeKanye 更新时间:11/14/2022 访问量:65
有没有办法使用扫描仪读取包括空格在内的完整字符串,而无需读取整行?
Is there a way to use scanner to read in a full string including the spaces, without reading the full line?
问:
假设我的文本文件如下所示:
John Doe 18 male
Amy hun 19 female
我需要像这样将其读入数组
while(reader.hasNextLine()){
result[i] = new Person(reader.next(),reader.next(),reader.next());
reader.nextLine();
i++;
}
但它一直搞砸我的数组,因为它将每个空格视为分隔符并且不使用它,其中列由空格分隔。
我尝试在扫描仪上使用分隔符来空格,但出现错误:线程“main”java.util.NoSuchElementException 中的异常。尝试了一些东西,但也没有运气。我也不能只将两个名称作为单独的字符串读取,因为有些行只有一个名称。
答:
0赞
Hovercraft Full Of Eels
11/14/2022
#1
您需要阅读每一行文本,然后使用正则表达式或“正则表达式”解析该行。正则表达式是一种灵活的方法,用于抓取与某些规则匹配的字符串部分。例如,如果逐行遍历文件,则使用以下命令抓取每一行:reader.nextLine()
while (reader.hasNextLine()) {
String line = reader.nextLine();
// ...
}
现在保存文件中的一行,例如line
"John Doe 18 male"
然后,您需要将这一行拆分为 3 个子字符串,分别代表姓名、年龄和性别,它们由文本后跟数字后跟文本表示,所有子字符串均由空格(空格)分隔
如果调用 String,则可以使用正则表达式,该正则表达式将根据以下规则划分 String:.split(...)
String regex = "(?<=\\d)\\s+|\\s+(?=\\d)";
这之所以有效,是因为正则表达式在数字后跟空格:或空格后跟数字处拆分:使用正则表达式前瞻和后视规则。"(?<=\\d)\\s+|\\s+(?=\\d)"
(?<=\\d)\\s+
\\s+(?=\\d)
这会将字符串拆分为标记:{"John Doe", "18", "male"}
整个事情可能看起来像:
List<Person> personList = new ArrayList<>();
String regex = "(?<=\\d)\\s+|\\s+(?=\\d)";
while (reader.hasNextLine()) {
String line = reader.nextLine();
String[] tokens = line.split(regex);
Person person = new Person(tokens[0], tokens[1], tokens[2]);
// or perhaps:
// Person person = new Person(tokens[0], Integer.parseInt(tokens[1]), tokens[2]);
personList.add(person);
}
0赞
Bohemian
11/14/2022
#2
适当设置扫描仪的分隔符:
reader.useDelimiter("(?<=\\d)\\s+|\\s+(?=\\d)|\n");
观看现场演示。
这会将分隔符设置为:
- “数字后面的一些空格”,或者
- “数字前的一些空格”,或
- “换行符”
有了这个,你可以按原样使用你的代码(请参阅下面的测试代码)。
一些测试代码:
public static void main(String[] args) {
String input ="John Doe 18 male\nAmy hun 19 female\n";
Scanner reader = new Scanner(input).useDelimiter("(?<=\\d)\\s+|\\s+(?=\\d)|\n");
Person[] result = new Person[10];
int i = 0;
while (reader.hasNext()) {
result[i++] = new Person(reader.next(), reader.next(), reader.next());
}
Arrays.stream(result).filter(Objects::nonNull).forEach(System.out::println);
}
static class Person {
private final String name;
private final String age;
private final String gender;
Person(String name, String age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
", gender='" + gender + '\'' +
'}';
}
}
输出:
Person{name='John Doe', age='18', gender='male'}
Person{name='Amy hun', age='19', gender='female'}
评论
String line = reader.nextLine();
"John Doe 18 male"
String[] tokens = lineOfText.split("(?<=\\d)\\s+|\\s+(?=\\d)");
{"John Doe", "18", "male"}
"(?<=\\d)\\s+|\\s+(?=\\d)"
"(?<=\\d)\\s+
\\s+(?=\\d)"