我想制作一个正则表达式,可以帮助我摆脱下面的代码 -
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);
}
}
}
答案 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])$
你可以试试这个正则表达式。参见演示。
答案 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
是最好的选择,因为它易于阅读且意图非常明确。