3

我想知道是否有任何好方法可以从 Groovy 甚至 Java 中的格式化字符串中读取单个属性。

我有一个字符串,其中包含一些用空格分隔的属性。例如“2.1 20 真事”。顺序是固定的,并且“属性类型”是已知的(例如第一个是 Float,第二个是 Integer,等等)。我需要类似于 String.format() 但其他方式的东西。

我知道我可以手动拆分字符串并读取值,但这会使代码过于复杂,如下所示:

String[] parsedText = "2.1 20 Something true".split(delimiter)

try {
   firstVal = new Float(parsedText[0])
}
catch (NumberFormatException e) {
   throw new RuntimeException("Bad data [0th position in data string], cannot read[{$parsedData[0]}], cannot convert to float")
}
...

有没有更好的办法?我很确定至少在 Groovy 中是:-)

谢谢!

4

2 回答 2

11

Java Scanner类有一大堆方法用于抓取和解析字符串的下一部分,例如next(), nextInt(),nextDouble()等。

代码如下所示:

String input = "2.1 20 Something true";
Scanner s = new Scanner(input);
float f = s.nextFloat();
int i = s.nextInt();
String str = s.next(); // next() doesn't parse, you automatically get a string
boolean b = s.nextBoolean();

唯一需要注意的是:next()两者nextLine()都会让你得到字符串,但next()只会让你把字符串带到下一个空格。如果您希望字符串组件中有空格,则需要考虑这一点。

于 2012-09-04T09:56:19.283 回答
2

java.util 中的 Scanner 类应该为您完成这项工作。在从输入中读取时,您需要考虑更多情况。

在您的情况下,您可以连续调用扫描仪方法或使用正则表达式明确定义“格式字符串”并将其保持在一个地方。通过这种方式,您将受益于立即进行验证。

//calling methods in row
{
    Scanner sc = new Scanner("2.1 20 Something true");
    float f = sc.nextFloat();
    int i = sc.nextInt();
    String s = sc.nextLine();

    System.out.print(String.format("%s\t%.2f\t%x\n", s, f, i));

    sc.close();
}
//using regexp
{
    Scanner sc = new Scanner("2.1 20 Something true");
    sc.findInLine("(\\d+[\\.,]?\\d*)\\s(\\d+)(\\s.*)$");
    MatchResult result = sc.match();
    float f = Float.parseFloat(result.group(1));
    int i = Integer.parseInt(result.group(2));
    String s = result.group(3);

    System.out.print(String.format("%s\t%.2f\t%x\n", s, f, i));

    sc.close();
}

Scanner 类有不同的构造函数来使用具有以下类型的对象的类:File、InputStream、Readable、ReadableByteChannel 和 String 的示例。

请注意,此类是区域设置感知的,因此它的行为可能会有所不同,具体取决于系统设置(某些国家/地区使用 coma 而不是浮点数等...)。您可以覆盖区域设置。

这是综合参考:http ://docs.oracle.com/javase/1.5.0/docs/api/java/util/Scanner.html

于 2012-09-04T10:50:57.000 回答