我想知道如何在Groovy甚至Java中从格式化字符串中读取单个属性有什么好方法。
我有一个包含由空格分隔的属性的字符串。例如“2.1 20 Something true”。订单是固定的,“属性类型”是已知的(例如,首先是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中是: - )
谢谢!
答案 0 :(得分: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()
只能获取到下一个空格的字符串。如果您希望字符串组件中包含空格,则需要考虑到这一点。
答案 1 :(得分:2)
java.util中的扫描程序类应该为您完成工作。在阅读输入时,需要考虑更多的情况。
在您的情况下,您可以连续调用扫描仪方法或使用正则表达式明确定义“格式字符串”并将其保持在一个位置。 通过这种方式,您可以立即进行验证。
//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中使用的示例。
请注意,此类可以识别区域设置,因此它的行为可能会有所不同,具体取决于系统设置(某些国家/地区使用昏迷而不是指向浮点等等)。您可以覆盖区域设置。
以下是全面参考:http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Scanner.html