जवाब के बाद से Casimir मैं इसे लेने का फैसला किया एक सा आगे और लागू करने के लिए कुछ कोड वास्तव में पार्स integers के रूप में अच्छी तरह से, नीचे शामिल है. यह शामिल करता है ऋण और प्लस प्रतीकों यहां तक कि हालांकि वे कर रहे हैं आधिकारिक तौर पर हिस्सा नहीं के पूर्णांक शाब्दिक रूप में वर्णित 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;
}
}
मैं भी करने की कोशिश की करने के लिए उपयोग कोड को खोजने के लिए कई integers से एक स्ट्रिंग है, लेकिन है कि नहीं था अच्छी तरह से जाना. समस्या यह है कि कुछ अमान्य literals के रूप में इस तरह 0__0
स्वीकार कर लिया गया के रूप में दो literals के साथ मूल्य शून्य; नहीं बिल्कुल आप क्या चाहते हैं. तो कृपया का उपयोग करें regex केवल अगर पता लगाने के लिए एक स्ट्रिंग वास्तव में है एक पूर्णांक के लिए और अलग पूर्णांकों का उपयोग कर उदाहरण के लिए String.split(SEPARATOR_REGEX)
.
अजीब बात है पर्याप्त, मेरे ग्रहण आईडीई स्वीकार किया 0__0
के रूप में एक शाब्दिक यहां तक कि अगर यह आधिकारिक तौर पर है नहीं करने के लिए अनुरूप JLS. नहीं एक biggy है, लेकिन अजीब कोई नहीं-the-कम.
?
होना चाहिए*
?