在 Java 中解析 C 风格程序员的整数
Parse a C-style programmer's integer in Java
这个很短,但我找不到答案。
是否有 jdk 例程可以将 String
解析为 int
,以及 autodetect 并转换 C 风格的编程约定:
- 123(十进制)
- 0x1ABC(十六进制)
- 0x1abc(十六进制)
- 0777(八进制)
谢谢!
编辑:
让我在这里说清楚,我知道我可以手动执行此方法。我已经这样做了!我知道基数是什么以及关于 Integer.parse(..., radix)
!我想问的是,JDK 不是已经有了处理所有情况的方法吗?一条线适用于整个地段...
我不记得标准中有这样的函数 JDK。
如果你想自动检测样式,你可以用 switch-case
或 Strategy pattern
.
编写辅助函数
首先,检查数字字符串是否以 0x
开头,如果没有 - 检查它是否完全以 0
开头。但如果你有二进制数,这将不起作用。但是你的问题里没有这个^_^.
参见Integer.parse(String s, radix)方法。
附上示例代码:
public class RadixDetector {
private static final int RADIX_HEX = 16;
private static final int RADIX_OCTAL = 8;
public static int detectRadix(String number) {
if (number.toLowerCase().startsWith("0x") && isValidHex(number)) {
return RADIX_HEX;
} else if (number.startsWith("0") && isValidOctal(number)) {
return RADIX_OCTAL;
} else {
throw new NumberFormatException("Unknown or unable to detect radix for: " + number);
}
}
public static boolean isValidHex(String number) {
Pattern hexPattern = Pattern.compile("0[xX][0-9a-fA-F]+");
return hexPattern.matcher(number).matches();
}
public static boolean isValidOctal(String number) {
Pattern hexPattern = Pattern.compile("0[1-7][0-7]*");
return hexPattern.matcher(number).matches();
}
}
并测试:
public class NumberRadixTests {
@Test
public void testRadixDetection() {
assertEquals(16, RadixDetector.detectRadix("0xabcd"));
assertEquals(16, RadixDetector.detectRadix("0xABCD"));
assertEquals(16, RadixDetector.detectRadix("0xAFFF"));
assertEquals(16, RadixDetector.detectRadix("0x0"));
assertEquals(16, RadixDetector.detectRadix("0X0"));
assertEquals(16, RadixDetector.detectRadix("0XFFF"));
assertEquals(8, RadixDetector.detectRadix("0123"));
assertEquals(8, RadixDetector.detectRadix("011"));
assertEquals(8, RadixDetector.detectRadix("0777"));
assertEquals(8, RadixDetector.detectRadix("0666"));
}
@Test
public void testHexRegex() {
assertTrue(RadixDetector.isValidHex("0xabcd"));
assertTrue(RadixDetector.isValidHex("0Xabcd"));
assertTrue(RadixDetector.isValidHex("0xAbcd"));
assertTrue(RadixDetector.isValidHex("0xa0cd"));
assertTrue(RadixDetector.isValidHex("0x9bc1"));
assertTrue(RadixDetector.isValidHex("0x9bc1"));
assertFalse(RadixDetector.isValidHex("x9bc1"));
assertFalse(RadixDetector.isValidHex("0xbtc1"));
assertFalse(RadixDetector.isValidHex("0xx9bc1"));
assertFalse(RadixDetector.isValidHex("00x9bc1"));
assertFalse(RadixDetector.isValidHex("0x9pc1"));
assertFalse(RadixDetector.isValidHex("0x"));
assertFalse(RadixDetector.isValidHex("077"));
}
@Test
public void testOctalRegex() {
assertTrue(RadixDetector.isValidOctal("077"));
assertTrue(RadixDetector.isValidOctal("067"));
assertTrue(RadixDetector.isValidOctal("07777"));
assertTrue(RadixDetector.isValidOctal("017"));
assertFalse(RadixDetector.isValidOctal("08"));
assertFalse(RadixDetector.isValidOctal("8"));
assertFalse(RadixDetector.isValidOctal("777"));
assertFalse(RadixDetector.isValidOctal("0x"));
assertFalse(RadixDetector.isValidOctal("08"));
assertFalse(RadixDetector.isValidOctal("01238"));
}
}
这个很短,但我找不到答案。
是否有 jdk 例程可以将 String
解析为 int
,以及 autodetect 并转换 C 风格的编程约定:
- 123(十进制)
- 0x1ABC(十六进制)
- 0x1abc(十六进制)
- 0777(八进制)
谢谢!
编辑:
让我在这里说清楚,我知道我可以手动执行此方法。我已经这样做了!我知道基数是什么以及关于 Integer.parse(..., radix)
!我想问的是,JDK 不是已经有了处理所有情况的方法吗?一条线适用于整个地段...
我不记得标准中有这样的函数 JDK。
如果你想自动检测样式,你可以用 switch-case
或 Strategy pattern
.
首先,检查数字字符串是否以 0x
开头,如果没有 - 检查它是否完全以 0
开头。但如果你有二进制数,这将不起作用。但是你的问题里没有这个^_^.
参见Integer.parse(String s, radix)方法。
附上示例代码:
public class RadixDetector {
private static final int RADIX_HEX = 16;
private static final int RADIX_OCTAL = 8;
public static int detectRadix(String number) {
if (number.toLowerCase().startsWith("0x") && isValidHex(number)) {
return RADIX_HEX;
} else if (number.startsWith("0") && isValidOctal(number)) {
return RADIX_OCTAL;
} else {
throw new NumberFormatException("Unknown or unable to detect radix for: " + number);
}
}
public static boolean isValidHex(String number) {
Pattern hexPattern = Pattern.compile("0[xX][0-9a-fA-F]+");
return hexPattern.matcher(number).matches();
}
public static boolean isValidOctal(String number) {
Pattern hexPattern = Pattern.compile("0[1-7][0-7]*");
return hexPattern.matcher(number).matches();
}
}
并测试:
public class NumberRadixTests {
@Test
public void testRadixDetection() {
assertEquals(16, RadixDetector.detectRadix("0xabcd"));
assertEquals(16, RadixDetector.detectRadix("0xABCD"));
assertEquals(16, RadixDetector.detectRadix("0xAFFF"));
assertEquals(16, RadixDetector.detectRadix("0x0"));
assertEquals(16, RadixDetector.detectRadix("0X0"));
assertEquals(16, RadixDetector.detectRadix("0XFFF"));
assertEquals(8, RadixDetector.detectRadix("0123"));
assertEquals(8, RadixDetector.detectRadix("011"));
assertEquals(8, RadixDetector.detectRadix("0777"));
assertEquals(8, RadixDetector.detectRadix("0666"));
}
@Test
public void testHexRegex() {
assertTrue(RadixDetector.isValidHex("0xabcd"));
assertTrue(RadixDetector.isValidHex("0Xabcd"));
assertTrue(RadixDetector.isValidHex("0xAbcd"));
assertTrue(RadixDetector.isValidHex("0xa0cd"));
assertTrue(RadixDetector.isValidHex("0x9bc1"));
assertTrue(RadixDetector.isValidHex("0x9bc1"));
assertFalse(RadixDetector.isValidHex("x9bc1"));
assertFalse(RadixDetector.isValidHex("0xbtc1"));
assertFalse(RadixDetector.isValidHex("0xx9bc1"));
assertFalse(RadixDetector.isValidHex("00x9bc1"));
assertFalse(RadixDetector.isValidHex("0x9pc1"));
assertFalse(RadixDetector.isValidHex("0x"));
assertFalse(RadixDetector.isValidHex("077"));
}
@Test
public void testOctalRegex() {
assertTrue(RadixDetector.isValidOctal("077"));
assertTrue(RadixDetector.isValidOctal("067"));
assertTrue(RadixDetector.isValidOctal("07777"));
assertTrue(RadixDetector.isValidOctal("017"));
assertFalse(RadixDetector.isValidOctal("08"));
assertFalse(RadixDetector.isValidOctal("8"));
assertFalse(RadixDetector.isValidOctal("777"));
assertFalse(RadixDetector.isValidOctal("0x"));
assertFalse(RadixDetector.isValidOctal("08"));
assertFalse(RadixDetector.isValidOctal("01238"));
}
}