如何检查字符串是否符合以下格式:
<number>,<number>,<number>
e.g。
3.0, 87546,0.8273456
即。三个以逗号分隔的值,可以解析为双精度数。有时字符串将包含其他内容(例如Text,More text,42
或anything, really
),在这种情况下,我只需要忽略它并继续解析下一个字符串。
现在我只是尝试解析字符串,就好像它符合预期的格式,并捕获任何产生的异常。什么是更智能,更便宜的方式?希望没有抛出/捕获异常?
String[] parsedLine = line.trim().split(",");
if (parsedLine.length == 3) {
try {
xCoordinate = Double.parseDouble(parsedLine[0]);
yCoordinate = Double.parseDouble(parsedLine[1]);
groundElevation = Double.parseDouble(parsedLine[2]);
} catch (NumberFormatException nfe) {
//This line does not contain numbers exclusively.
//Assume it's a header/comment.
//Do nothing.
}
} else {
//This is not in the expected x,y,z format.
//Assume it's a header/comment.
//Do nothing.
}
答案 0 :(得分:2)
Regular Expressions是你的朋友;这是implement a pattern in Java的一个例子。
答案 1 :(得分:2)
没有更清洁的方式。你的代码很好。
你问:“但不应该例外”只能在特殊条件下使用“?我在这里使用它们当然是理所当然的。”
好吧,Java没有任何Double.isValid(String)
方法。如果有,你可以使用它,但事实并非如此。即使这样,你也必须解析两次:一次检查它是否为double,一次得到double值。
你所拥有的是一种常见的习语,我怀疑正则表达式会比你所拥有的更具可读性和速度。
答案 2 :(得分:2)
您现在所拥有的可能是最可靠的(并且在我看来最容易理解)实施方案。
我不会改变它,除非我从分析器中得到具体的证据,证明它是一个整体瓶颈(无论是CPU使用率还是创建的垃圾量)。
答案 3 :(得分:2)
我认为并不贵。 String.split()
将从您的参数中创建Pattern
,并将字符串拆分为。
如果您担心异常的代价,那么您可以创建一个更复杂的模式来匹配您的字符串,您可能不会拥有它们:
final Pattern pattern = Pattern.compile("^(\\d+(\\.\\d+)?),(\\d+(\\.\\d+)?),(\\d+(\\.\\d+)?)$");
final Matcher matcher = pattern.matcher(line);
if (matcher.matches()) {
xCoordinate = Double.parseDouble(matcher.group(1));
// ...
}
答案 4 :(得分:2)
正则表达式将是解决此问题的自然方法。我和其他许多人会立即使用这种方法。但是,您在问题中提到您正在寻找更便宜的解决方案。就使用的资源而言,正则表达式可能更昂贵。
在回应您的评论时“不应该例外地在异常条件下使用”,我会说这个问题 是一个例外情况;以这种方式使用异常的问题创建了一个更优雅的解决方案。
您当前的解决方案简单,简洁,易于理解(因此易于维护)。如果它有效,我不会浪费时间来改变它。
答案 5 :(得分:1)
您可以使用正则表达式来自here的双打:
public boolean matches(String str) {
final String Digits = "(\\p{Digit}+)";
final String HexDigits = "(\\p{XDigit}+)";
final String Exp = "[eE][+-]?"+Digits;
final String fpRegex =
("[\\x00-\\x20]*"+ // Optional leading "whitespace"
"[+-]?(" + // Optional sign character
"NaN|" + // "NaN" string
"Infinity|" + // "Infinity" string
// A decimal floating-point string representing a finite positive
// number without a leading sign has at most five basic pieces:
// Digits . Digits ExponentPart FloatTypeSuffix
//
// Since this method allows integer-only strings as input
// in addition to strings of floating-point literals, the
// two sub-patterns below are simplifications of the grammar
// productions from the Java Language Specification, 2nd
// edition, section 3.10.2.
// Digits ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt
"((("+Digits+"(\\.)?("+Digits+"?)("+Exp+")?)|"+
// . Digits ExponentPart_opt FloatTypeSuffix_opt
"(\\.("+Digits+")("+Exp+")?)|"+
// Hexadecimal strings
"((" +
// 0[xX] HexDigits ._opt BinaryExponent FloatTypeSuffix_opt
"(0[xX]" + HexDigits + "(\\.)?)|" +
// 0[xX] HexDigits_opt . HexDigits BinaryExponent FloatTypeSuffix_opt
"(0[xX]" + HexDigits + "?(\\.)" + HexDigits + ")" +
")[pP][+-]?" + Digits + "))" +
"[fFdD]?))" +
"[\\x00-\\x20]*");// Optional trailing "whitespace"
String pattern=fpRegex + "," + fpRegex + "," + fpRegex;
return str.matches(pattern);
}
答案 6 :(得分:1)
一个好的开始是使用Pattern类:boolean b = Pattern.matches(".*,.*,.*", str);
但是,为了确保您拥有数字,您必须拥有更复杂的正则表达式:
String str = "3.0,87546,0.8273456";
boolean b = Pattern.matches("^(\\d+(\\.\\d+)?),(\\d+(\\.\\d+)?),(\\d+(\\.\\d+)?)$", str);
if (b) {
System.out.println("matches");
} else {
System.out.println("does not match");
}
// output: matches
编辑:我看到KARASZI已经在速度上打败了我,但是代码还在这里...
答案 7 :(得分:0)
您可以使用正则表达式\ d来表示数字。所以像这样
\ d +,\ d +,\ d +
抱歉未经测试:)
答案 8 :(得分:0)
在全文中使用此正则表达式 这假设数字和逗号之间没有空格,您可以进行相关更改以添加可选空格字符
[0-9]+(\.[0-9]*)?,[0-9]+(\.[0-9]*)?,[0-9]+(\.[0-9]*)?
我刚做了修改
[0-9]+(\.[0-9]*)?\s*,\s*[0-9]+(\.[0-9]*)?\s*,\s*[0-9]+(\.[0-9]*)?
这将是对空间友好的 当然,你必须测试它