And from the point of view of Java,
just pointing that it's missing such a
similar method, despite we could get
it through things like:
boolean isInteger = Pattern.matches("^\d*$", myString);
要预测Integer.parseInt(myString)
是否会抛出异常,还有更多的工作要做。字符串可能以-
开头。此外,int不能超过10个有效数字。因此,更可靠的表达式应该是^-?0*\d{1,10}$
。但即使这个表达式也无法预测每个异常,因为它仍然太不精确。
生成可靠的正则表达式是可能的。但它会非常长。也可以实现一个方法来精确确定是否会抛出parseInt异常。它可能看起来像这样:
static boolean wouldParseIntThrowException(String s) {
if (s == null || s.length() == 0) {
return true;
}
char[] max = Integer.toString(Integer.MAX_VALUE).toCharArray();
int i = 0, j = 0, len = s.length();
boolean maybeOutOfBounds = true;
if (s.charAt(0) == '-') {
if (len == 1) {
return true;
}
i = 1;
max[max.length - 1]++;
}
while (i < len && s.charAt(i) == '0') {
i++;
}
if (max.length < len - i) {
return true;
} else if (len - i < max.length) {
maybeOutOfBounds = false;
}
while (i < len) {
char digit = s.charAt(i++);
if (digit < '0' || '9' < digit) {
return true;
} else if (maybeOutOfBounds) {
char maxdigit = max[j++];
if (maxdigit < digit) {
return true;
} else if (digit < maxdigit) {
maybeOutOfBounds = false;
}
}
}
return false;
}
虽然我不知道哪个版本更有效率,但它主要取决于上下文需要什么样的检查。
在C#中,如果要“检查”字符串是否可以转换,您将使用TryParse。如果返回true,则作为副产品同时进行了转换。这是一个很棒的功能,我认为只需重新实现parseInt以返回null而不是抛出异常即可。
但是,如果您不想重新实现解析方法,仍然可以方便地提供一组可以根据情况使用的方法。它们可能看起来像这样:
private static Pattern QUITE_ACCURATE_INT_PATTERN = Pattern.compile("^-?0*\\d{1,10}$");
static Integer tryParseIntegerWhichProbablyResultsInOverflow(String s) {
Integer result = null;
if (!wouldParseIntThrowException(s)) {
try {
result = Integer.parseInt(s);
} catch (NumberFormatException ignored) {
}
}
return result;
}
static Integer tryParseIntegerWhichIsMostLikelyNotEvenNumeric(String s) {
Integer result = null;
if (s != null && s.length() > 0 && QUITE_ACCURATE_INT_PATTERN.matcher(s).find()) {
try {
result = Integer.parseInt(s);
} catch (NumberFormatException ignored) {
}
}
return result;
}
static Integer tryParseInteger(String s) {
Integer result = null;
if (s != null && s.length() > 0) {
try {
result = Integer.parseInt(s);
} catch (NumberFormatException ignored) {
}
}
return result;
}
static Integer tryParseIntegerWithoutAnyChecks(String s) {
try {
return Integer.parseInt(s);
} catch (NumberFormatException ignored) {
}
return null;
}