正则表达式,以确保字符串包含不多于一个数字

时间:2017-05-18 12:20:00

标签: java regex

我想检查字符串是否只包含一个数字,如果它包含多个数字则抛出异常:

(d *?\ d + \ d + \ d + d *)

private static void assertOnlyOneNumber(String input) {
        if (input.matches(("(D*?\\d+\\D+\\d+D*)"))) {
            throw new RuntimeException(
                    "Assertion failed! String contains more than a single number: "
                    + input);
        }
    }

所以,例如以下内容应匹配并抛出异常:

  • 42' 12
  • 1h22min
  • 1时23分22秒
  • 约120分钟,200分钟,300分钟

以下内容不应匹配,因此被视为有效:

  • 12分钟
  • 141'
  • ca.22min

看起来我的正则表达式没问题,但是很容易弄错,所以我的问题。

背景:基本上我从字符串字段转换为整数字段,其中我将字符串字段解释为持续时间(以分钟为单位)。因此,我首先运行此检查以确保字符串中没有多个数字,然后我删除已知标记的固定数组(例如' Minutes',' min&# 39;等等)最后尝试通过Integer.parseInt(),如果我可以转换它。

如果是,我会在几分钟内得到我的持续时间,否则我会抛出异常。

4 个答案:

答案 0 :(得分:3)

如果你想保持一行,你仍然可以简化你的正则表达式.*\\d\\D+\\d.*

但是,进行多项检查可能更容易,特别是如果您想将其更改为“不超过x数字”:

Matcher m = Pattern.compile("\\d+").matcher(input);
for (int i = 0; i < allowedNumber; i++)
    m.find();
if (m.find())
    throw new RuntimeException(...);

两种方式之间的合并是根据允许的出现次数构建正则表达式:

String regex = Stream.generate(() -> "\\d+").limit(allowedNumber + 1).collect(joining("\\D+", ".*", ".*"))

// non-stream equivalent
String regex = ".*\\d+";
for (int i = 0; i < allowedNumber; i++) {
    regex += "\\D+\\d+";
}
regex += ".*";

if (input.matches(regex)) {
    throw new RuntimeException(...);
}

答案 1 :(得分:1)

您可以使用:

private static void assertOnlyOneNumber(String input) {
        if (input.matches(".*\\d+\\D+\\d.*")) {
            throw new RuntimeException(
                    "Assertion failed! String contains more than a single number: "
                    + input);
        }
    }

RegEx Demo

正则表达式.*\\d+\\D+\\d.*会将输入与至少2组数字匹配。

答案 2 :(得分:1)

这应该有效:

private static final Pattern NUMBER_PATTERN = Pattern.compile("\\d+");

private static void assertOnlyOneNumber(String input) {
    Matcher m = NUMBER_PATTERN.matcher(input);
    int count = 0;
    while(m.find()) count++;
    // != 1 ensure that the input contains exactly one number (not more, not less)
    // if "not more than one" is the intended behaviour just use > 1
    if(count != 1) {
        throw new RuntimeException(
                "Assertion failed! String contains more than a single number: "
                + input);
    }
}

答案 3 :(得分:1)

试试这个:

(?:\d+(?:[^\d\n]|$)+?){2,}

说明:

                        // Matches group composed of
(?:\d+                  // number and
      (?:[^\d\n]|       // not number OR
                 $)+?    //    end of line
 ) {2,}                 // at least two times

Demo