Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 正则表达式以确保字符串包含的数字不超过一个_Java_Regex - Fatal编程技术网

Java 正则表达式以确保字符串包含的数字不超过一个

Java 正则表达式以确保字符串包含的数字不超过一个,java,regex,Java,Regex,我想检查字符串是否只包含一个数字,如果它包含多个数字,则抛出异常: (D*?\D+\D+\D+D*) 因此,例如,以下内容应匹配并引发异常: 42'12 1h22min 01:23:22 约120分钟,200分钟,300分钟 以下内容不应匹配,因此被视为有效: 12分钟 141' 约22分钟 我的正则表达式似乎运行正常,但很容易出错,所以我的问题是 背景:基本上,我将字符串字段转换为整数字段,将字符串字段解释为以分钟为单位的持续时间。因此,我首先运行此检查以确保字符串中的数字不超过一个,

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

(D*?\D+\D+\D+D*)

因此,例如,以下内容应匹配并引发异常:

  • 42'12
  • 1h22min
  • 01:23:22
  • 约120分钟,200分钟,300分钟
以下内容不应匹配,因此被视为有效:

  • 12分钟
  • 141'
  • 约22分钟
我的正则表达式似乎运行正常,但很容易出错,所以我的问题是

背景:基本上,我将字符串字段转换为整数字段,将字符串字段解释为以分钟为单位的持续时间。因此,我首先运行此检查以确保字符串中的数字不超过一个,然后剥离已知标记的固定数组(如“分钟”、“分钟”等),最后尝试通过Integer.parseInt()进行转换


如果是,我以分钟为单位获得了持续时间,否则我将抛出一个异常。

如果要将If保留在一行中,您仍然可以将regex简化为
*\\d\\d+\\d.*

不过,执行多个检查可能更容易,尤其是如果您想将其更改为“不超过x个数字”:

Matcher m=Pattern.compile(\\d+).Matcher(输入);
对于(int i=0;i
两种方法之间的合并基于允许出现的次数构建正则表达式:

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(...);
}
String regex=Stream.generate(()->“\\d+”).limit(allowedNumber+1).collect(加入(“\\d+”,“*”,“*”))
//非流当量
字符串regex=“.*\\d+”;
对于(int i=0;i
您可以使用:

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
*\\d+\\d+\\d.*
将一个输入与至少两组数字匹配。

这应该可以:

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);
    }
}
试试这个:

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

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

嗯?你提到的每一个输入都包含不止一个数字。@Michael我想他指的是一个多位数(在数学意义上),而不是一个数字字符。+我喜欢它,因为它易于阅读,并且降低了代码的复杂性IMHO--我只想用大括号表示,呵呵;)@老实说,戴吉·贾恩也喜欢我。但是您的IDE会处理这些;)+较短的正则表达式为1!不过,我不太喜欢嵌套的if结构。至于构建正则表达式的流API方式,allowedNumber在我目前的情况下是零,对吗?看起来很花哨,但我不知道一周后我是否能理解它的功能:)但我想这只是我和流API。@SebastianRiemer您可以使用for循环将堆叠的if展平,在该循环中调用
find()
allowedNumber
次。之后,再次调用它,如果它仍然返回true,则抛出异常。对于流,
allowedNumber
将是1,当输入与正则表达式匹配时,抛出异常。此流也可以轻松地替换为循环。我将把它添加到答案中。@SebastianRiemer我还将堆叠的
if
替换为
for循环
。当然,只要
find
返回
false
(特别是如果您想要更大的
allowedNumbers
),您就可以更早地中断循环。。*\\d\\d+\\d.*也可以吗?我想这并不重要,因为我们在
matches
方法中使用了这个方法,所以我们需要匹配完整的输入来获得返回的
true
值。如果您使用
模式,Mtacher
然后使用
matcher.find()
然后使用
\\d\\d+\\d
就可以了。哦,对不起,没有正确阅读您的评论,是的
*\\d\\d+\\d.
也可以。
(?:\d+(?:[^\d\n]|$)+?){2,}
                        // Matches group composed of
(?:\d+                  // number and
      (?:[^\d\n]|       // not number OR
                 $)+?    //    end of line
 ) {2,}                 // at least two times