후에서 답 Casimir 하기로 결정했다 조금 더 나아가 구현되는 코드를 실제로 구문 분석의 정수,뿐만 아니라 아래에 포함되어 있습니다. 그것이 포함되어 마이너스 플러스 상징하더라도 사람들은 공식적으로 일부의 정수 리터럴에서 설명한 대로 JLS;그들은 단항 연산자입니다.
package nl.owlstead.ifprops;
import java.math.BigInteger;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class JavaIntegerParser {
private static final Pattern BINARY = Pattern.compile("(0b)([01](?:_*[01])*)(L?)", Pattern.CASE_INSENSITIVE);
private static final Pattern OCTAL = Pattern.compile("(0)([0-7](?:_*[0-7])*)(L?)", Pattern.CASE_INSENSITIVE);
private static final Pattern DECIMAL = Pattern.compile("()(0|(?:[1-9](?:_*[0-9])*))(L?)", Pattern.CASE_INSENSITIVE);
private static final Pattern HEXADECIMAL = Pattern.compile("(0x)([0-9a-f](?:_*[0-9a-f])*)(L?)", Pattern.CASE_INSENSITIVE);
// NOTE: OCTAL should be before DECIMAL if this is used to find the pattern
private static final Pattern SIGNED_INTEGER_LITERAL = Pattern.compile(
"(?:([+-])\\s*)?(" +
BINARY + "|" + OCTAL + "|" + DECIMAL + "|" + HEXADECIMAL +
")", Pattern.CASE_INSENSITIVE);
public static int parseJavaInteger(String javaInteger) throws NumberFormatException {
BigInteger value = parseIntegerAsBigInt(javaInteger);
try {
return value.intValueExact();
} catch (@SuppressWarnings("unused") ArithmeticException e) {
throw new NumberFormatException("Number is not between Integer.MIN_VALUE and Integer.MAX_VALUE");
}
}
public static long parseJavaLong(String javaLong) throws NumberFormatException {
BigInteger value = parseIntegerAsBigInt(javaLong);
try {
return value.longValueExact();
} catch (@SuppressWarnings("unused") ArithmeticException e) {
throw new NumberFormatException("Number is not between Integer.MIN_VALUE and Integer.MAX_VALUE");
}
}
private static BigInteger parseIntegerAsBigInt(String javaLiteral) {
Matcher intMatcher = SIGNED_INTEGER_LITERAL.matcher(javaLiteral);
if (!intMatcher.matches()) {
throw new NumberFormatException(javaLiteral + " is not recognized as a Java integer literal");
}
String signGroup = intMatcher.group(1);
String prefixAndValueGroup = intMatcher.group(2);
String radixGroup = "";
String valueGroup = "";
// String longGroup = "";
List<Pattern> patterns = List.of(BINARY, OCTAL, DECIMAL, HEXADECIMAL);
for (Pattern pattern : patterns) {
Matcher specificMatcher = pattern.matcher(prefixAndValueGroup);
if (specificMatcher.matches()) {
radixGroup = specificMatcher.group(1);
valueGroup = specificMatcher.group(2);
// longGroup = specificMatcher.group(3);
break;
}
}
if (valueGroup == null) {
throw new RuntimeException("Number both matches but doesn't contain a value (parser error)");
}
BigInteger sign = signGroup != null && signGroup.matches("-") ? BigInteger.ONE.negate() : BigInteger.ONE;
int radix;
switch (radixGroup.toLowerCase()) {
case "0b":
radix = 2;
break;
case "0":
radix = 8;
break;
case "":
radix = 10;
break;
case "0x":
radix = 16;
break;
default:
throw new RuntimeException();
}
BigInteger value = new BigInteger(valueGroup.replaceAll("_", ""), radix).multiply(sign);
return value;
}
}
도를 사용하여 코드를 찾아 여러 정수 문자열에서,하지만 잘되지 않았다. 문제는 그 어떤 잘못된 리터럴 등 0__0
었으로 받아들여 두 리터럴 가치로 정확하게 당신이 원하는 무슨이 아닙. 그래서를 이용하시기 바랍 regex 만을 감지하는 경우 문자열은 실제로 정수 및 별도의 정수를 사용하여 예를 들어 String.split(SEPARATOR_REGEX)
.
충분히 재미 내 Eclipse IDE 받았다 0__0
리터럴 경우에도 그것은 공식적으로 준수하지 않을 JLS. 지는 빅지만,이상한 그럼에도 불구하고.
?
야*
?