字符串是否包含三个以逗号分隔的数字?

时间:2012-01-11 08:58:15

标签: java string parsing

如何检查字符串是否符合以下格式:

<number>,<number>,<number>

e.g。

3.0, 87546,0.8273456

即。三个以逗号分隔的值,可以解析为双精度数。有时字符串将包含其他内容(例如Text,More text,42anything, 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.
        }

9 个答案:

答案 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]*)?

这将是对空间友好的 当然,你必须测试它