使用扫描仪解析成对的字符串和双向量?

时间:2016-06-30 10:19:22

标签: java string parsing java.util.scanner

我很擅长用java解析文本文件。我的任务是, 我有一个包含字符串和Double值的文本文件,如下所示(示例):

字0.6478 1.74837 -0.2734 3.3475nextword 4.94756 -0.46372 3.29384 0.36475thirdword 5.92836(...)

(依此类推)

所以该文件包含单词后跟一致数量的单词,这些数字值以某种方式与它们所遵循的单词相关联。我最终想要的是一组字符串,其中包含文件中的所有单词以及每个单词的n个双关联矢量。

我的第一个想法是使用java.util.Scanner,但据我所知它只读取以空格分隔的项目,从我的示例中可以看出,组的最后一个数字和下一个组之间没有空格字。

有没有一种简单的方法可以在使用扫描仪时解决这个问题,或者使用不同的解析工具更容易解决这个问题?

我很感激任何提示

更新:

我有另一个问题。我的输入文件包含指数数字,如:-2.1961e-05 我的扫描仪读入数字:-2.1961和单词:e-05

是否有机会解决这类数字?

2 个答案:

答案 0 :(得分:0)

是的,默认情况下,Scanner仅使用空格(包括制表符和行分隔符)作为分隔符。但是,如果您熟悉正则表达式(正则表达式),则可以将自己的分隔符设置为:

  • whitespaces \s

或有

的地方
  • (?<=\d)
  • 之前的数字
  • 并且在(?!\d)
  • 之后没有数字
  • 不包括数字为点.的情况(因为12.34a34 a应该分开)(?![.])

(我在这里使用正则表达式的正面和负面预测机制。更多信息:http://www.regular-expressions.info/lookaround.html

因此,您可以将扫描仪设置为:

Scanner sc = new Scanner(yourData);
sc.useLocale(Locale.ENGLISH);//some locales use 12,34 for double, English ensures 12.34 format
sc.useDelimiter("\\s|(?<=\\d)(?!\\d)(?![.])");

重新更新:

sc.useDelimiter("\\s|(?<=\\d)(?!\\d)(?![.]|[eE]-?\\d+)");

答案 1 :(得分:0)

一种方法(没有Scanner)是用一个简单的正则表达式标记每一行,然后解析每个标记:

String line = "word 0.6478 1.74837 -0.2734 3.3475nextword 4.94756 -0.46372 3.29384 0.36475thirdword 5.92836";
String nonNumeric = "[^\\d.-]";
//alternative: nonNumeric="[a-zA-Z\\s]"
List<Double> doubles = Arrays
    .asList(line.split(nonNumeric))
    .stream()
    .filter(s -> !s.isEmpty())
    .map(s -> Double.parseDouble(s))
    .collect(Collectors.toList());
System.out.println(doubles);

结果:

[0.6478, 1.74837, -0.2734, 3.3475, 4.94756, -0.46372, 3.29384, 0.36475, 5.92836]