RegEx与否定角色类混淆了吗?

时间:2012-04-04 12:57:52

标签: java regex pattern-matching

我有以下方法:

protected BigDecimal stringToBigDecimal(String value) throws ParseException
{
    if (Pattern.matches("[\\d,.]+", value))
    {
        Number n = NumberFormat.getInstance().parse(value);

        return new BigDecimal(n.doubleValue());
    }
    else
    {
        throw new ParseException("Invalid String", -1);
    }
}

此值抛出异常(如预期的那样),因此此regExpr有效:

String wrongAmount = "1,U35,345.43";

但是当我尝试这个时:

protected BigDecimal stringToBigDecimal(String value) throws ParseException
{
    if (Pattern.matches("[\\D&&[^.,]]+", value))
    {
        throw new ParseException("Invalid String", -1);
    }

    Number n = NumberFormat.getInstance().parse(value);

    return new BigDecimal(n.doubleValue());
}

没有抛出异常,但为什么呢? 首先我认为“除了”表达式存在逻辑问题所以我尝试使用这种模式的这个值:

String wrongAmount = "1U3534543";

protected BigDecimal stringToBigDecimal(String value) throws ParseException
{
    if (Pattern.matches("[\\D]+", value))
    {
        throw new ParseException("Invalid String", -1);
    }

    Number n = NumberFormat.getInstance().parse(value);

    return new BigDecimal(n.doubleValue());
}

......但这不匹配?我对“非数字表达”\\D.的理解错误。该值包含“U”,为什么不匹配?

3 个答案:

答案 0 :(得分:2)

让我们剖析你的每一个模式:

Pattern.matches("[\\d,.]+", value)

匹配由一个或多个数字,逗号和点组成的任何字符串。

Pattern.matches("[\\D&&[^.,]]+", value)

你不能像在这里一样“组合”角色类。你[\\D&&[^.,]]所说的是“匹配任何非数字字符,除了点和逗号”。编写正则表达式的正确方法是:

[^\\d,.]   # match anything but digits, comma and dot

最后但并非最不重要:

Pattern.matches("[\\D]+", value)

这意味着:“匹配非空字符串完全非字母字符。”

Pattern.matches()尝试将整个字符串与正则表达式进行匹配。如果您尝试仅匹配部分字符串,则需要使用Matcher.find()

最后,您误解了+的工作原理。 +是一个量词,表示“1或更多”。它没有做你认为它正在做的事情。

答案 1 :(得分:0)

你没有正确地否定你的表达。

在第一个例子中,你说“如果我的输入只匹配数字,逗号和点”,那就没关系。

在你的第二个例子中(我不确定它是否符合你的意思,但这是另一个故事),你想说“如果输入只匹配非数字,非逗号,非点字符”,但您的输入包含数字,因此匹配不起作用。

在你的上一个例子中,同样的事情,你说“如果输入只匹配非数字字符”,但你的输入中还有数字

答案 2 :(得分:0)

我想你想要这个:

if (value.matches(".*[^\\d.,].*")) {
    throw new ParseException("Invalid String", -1);
}

请注意正面和背面添加了".*",因为String.matches()仅在模式与整个输入匹配时才会返回true

但是我会将其更改为否定匹配,因为它更容易阅读:

if (!value.matches("[\\d.,]+")) {
    throw new ParseException("Invalid String", -1);
}