正则表达式检查整数有效性和范围

时间:2015-04-07 16:51:49

标签: java regex

我想制作一个正则表达式,可以帮助我摆脱下面的代码 -

public class Test {
    public static void main(String[] args) {
        String test = "1026";
        int testToInt = 0;
        if(checkIfInteger(test))
            testToInt = Integer.parseInt(test);
        if(testToInt >= 1024 && testToInt <= 65535)
            System.out.println("Validity is perfect");
        else
            System.out.println("Validity is WRONG");
    }

    public static boolean checkIfInteger(String givenString) {
        boolean check = false;
        for(int i = 0; i < givenString.length(); i++) {
            if(givenString.charAt(i) >= '0' && givenString.charAt(i) >= '9')
                check = true;
            else {
                check = false;
                break;
            }
        }
        return check;
    }
}

基本上,它检查String是否仅包含数字,以及它的范围是否在1024到65535之间。

为此,我创建了以下正则表达式 -

"\b(102[4-9]|10[3-9][0-9]|1[1-9][0-9]{2}|[2-9][0-9]{3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[01][0-9]|6552[0-5])\b"

但是有很多值失败了。有人能给我一个更聪明/更正确的方法吗?

如果你想测试你的正则表达式,那么这是一个测试文件 -

public class Test {
    public static void main(String[] args) {

        for (int i = 0; i < 1024; i++) {
            if (String
                    .valueOf(i)
                    .matches(
                            "\b(102[4-9]|10[3-9][0-9]|1[1-9][0-9]{2}|[2-9][0-9]{3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[01][0-9]|6552[0-5])\b"))
                System.out.println("Hum " + i);
        }


        for (int i = 1025; i < (int) Math.pow(2, 16); i++) {
            if (!String
                    .valueOf(i)
                    .matches(
                            "\b(102[4-9]|10[3-9][0-9]|1[1-9][0-9]{2}|[2-9][0-9]{3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[01][0-9]|6552[0-5])\b"))
                System.out.println("Hum " + i);
        }

        for (int i = 0; i < 100; i++) {
            if (String
                    .valueOf((int)Math.pow(2, 16) + i)
                    .matches(
                            "\b(102[4-9]|10[3-9][0-9]|1[1-9][0-9]{2}|[2-9][0-9]{3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[01][0-9]|6552[0-5])\b"))
                System.out.println("Hum " + i);
        }

    }
}

5 个答案:

答案 0 :(得分:0)

在Java中,您需要使用双重转义符号,因此在修复此位后,您的正则表达式字符串如下所示:

String pattern = "\\b(102[4-9]|10[3-9][0-9]|1[1-9][0-9]{2}|[2-9][0-9]{3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[01][0-9]|6552[0-5])\\b";

这已经解决了很多问题,我只能得到这些“嗡嗡声”:

Hum 65526                                                                                                                                                           
Hum 65527                                                                                                                                                           
Hum 65528                                                                                                                                                           
Hum 65529                                                                                                                                                           
Hum 65530                                                                                                                                                           
Hum 65531                                                                                                                                                           
Hum 65532                                                                                                                                                           
Hum 65533                                                                                                                                                           
Hum 65534                                                                                                                                                           
Hum 65535 

现在,添加|6553[0-5]我得到了一个完全正常的正则表达式:

String pattern = "\\b(102[4-9]|10[3-9][0-9]|1[1-9][0-9]{2}|[2-9][0-9]{3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[012][0-9]|6552[0-5]|6553[0-5])\\b";

example program based on your testing code is available here

答案 1 :(得分:0)

在这里抛出一个Exception,IMO会比返回一个布尔值更好。

类似的东西:

public int parseAndCheck(String val, int low, int high) throws IllegalArgumentException {
  try {
    int num = Integer.parseInt(val);
    if (num < low || num > high) throw new IllegalArgumentException(val);
    return num;
  }
  catch (NumberFormatException ex) {
    throw new IllegalArgumentException(ex);
  }
}

答案 2 :(得分:0)

更改您的代码

发件人:

 testToInt = Integer.parseInt(test);
        if(testToInt >= 1024 && testToInt <= 65535)
            System.out.println("Validity is perfect");
        else
            System.out.println("Validity is WRONG");

try {
      testToInt = Integer.parseInt(test);
     if(testToInt >= 1024 && testToInt <= 65535)
        System.out.println("Validity is perfect");
    else
        System.out.println("Validity is WRONG");
    }  
      catch(NumberFormatException nfe)  
   {  
      System.out.println("Validity is WRONG"); 
   }  

答案 3 :(得分:0)

^(?:102[4-9]|10[3-9]\d|1[1-9]\d{2}|[2-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$

你可以试试这个正则表达式。参见演示。

https://regex101.com/r/sJ9gM7/70

答案 4 :(得分:0)

仅仅因为您可以使用正则表达式执行此操作并不意味着您应该。它不仅容易出错而且代码几乎不可读,而且速度很慢。

给定的代码如:

var intStrings = IntStream.range(0, 70000).mapToObj(Integer::toString).toArray(String[]::new);
var badStrings = IntStream.range(0, 70000).mapToObj(x -> "not an int " + x).toArray(String[]::new);

并使用来自 Wiktor's answer 的正则表达式:

var re = Pattern.compile("\\b(102[4-9]|10[3-9][0-9]|1[1-9][0-9]{2}|[2-9][0-9]{3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[012][0-9]|6552[0-5]|6553[0-5])\\b");

var matchCount = 0;
for (int i = 0, len = intStrings.length; i < len; i++) { 
  matchCount = re.matcher(intStrings[i]).matches() ? 1 + matchCount : matchCount;
  matchCount = re.matcher(badStrings[i]).matches() ? 1 + matchCount : matchCount;
} 

将比字符检查版本的相同迭代次数长大约十二倍:

boolean valid(String s) {
  var len = s.length();
  if (len > 5) { // anything longer than this will be > 65535
    return false;
  }
  for (int i = 0; i < len; i++) {
    var c = s.charAt(i);
    if (c < '0' || c > '9') {
      return false;
    }
  }
  try {
    var intVal = Integer.parseInt(s);
    return intVal >= 1024 && intVal <= 65535;
  } catch (NumberFormatException e) {
    throw new IllegalStateException(e); // never happen
  }
}

try/catch 版本,虽然简单得多 --

boolean valid(String s) {
  try {
    var intVal = Integer.parseInt(s);
    return intVal >= 1024 && intVal <= 65535;
  }
  catch (NumberFormatException e) {
    return false;
  }
}

-- 比字符检查版本慢约 450 倍,比正则表达式版本慢 35 倍。

也就是说,如果您希望几乎所有输入都有效,或者如果代码不会经常被调用,try/catch 最好的选择,因为它易于阅读且意图非常明确。