我的String
格式固定为: SPXXX-SPYYY.zip
我需要从String
中提取 XXX 和 YYY ,但如果例如 XXX 是003那么我想要 3 和不是003 。 ( YYY )相同。
我写了这两个代码:
1
String st = "SP003-SP012.zip";
String[] splitted = st.split("\\.");
splitted = splitted[0].split("-");
splitted = splitted[0].split("P");
Integer in = new Integer(splitted[1]);
System.out.println(in); //Will print 3
//The same for the other part of the String
2
Pattern pattern = Pattern.compile("^[a-zA-Z]+([0-9]+).*");
Matcher matcher = pattern.matcher(st);
int num = 0;
while (matcher.find()) {
num = Integer.parseInt(matcher.group(1));
System.out.println(num);
}
答案 0 :(得分:4)
如果格式总是相同,那么为什么不使用substring
?
String str = "SP003-SP456.zip";
int xxx = Integer.parseInt(str.substring(2, 5));
int yyy = Integer.parseInt(str.substring(8, 11));
或者,如果那些 XXX 和 YYY 不一定是数字,那么只需添加try-catch
:
String str = "SP003-SP456.zip";
int xxx, yyy;
try {
int xxx = Integer.parseInt(str.substring(2, 5));
}
catch(NumberFormatException e) {
xxx = 0;
}
try {
int yyy = Integer.parseInt(str.substring(8, 11));
}
catch(NumberFormatException e) {
yyy = 0;
}
答案 1 :(得分:1)
为什么第二个代码只返回第一个数字? (XXX)并错过了第二个?
因为你的正则表达式只定义它希望看到一系列数字,并且只有一个捕获组来捕获它们。正则表达式期望看到字母后跟数字,并且只找到一个与之匹配的东西。 (一旦消耗了第一个位,就没有剩下的字母,所以没有任何东西与你的[a-zA-Z]+
匹配。)我可能会定义一个匹配两个位的正则表达式,而不是尝试重复运行匹配器。
Pattern pattern = Pattern.compile("^[a-zA-Z]+([0-9]+)-([0-9]+).*");
...并使用生成的两个捕获组。 (另请注意,您可以使用\d
来匹配数字:
Pattern pattern = Pattern.compile("^[a-zA-Z]+(\\d+)-(\\d+).*");
......但那是旁注。)
为此目的使用正则表达式比我建议的第一个代码更好吗?
这取决于你,这是一个判断。对于这种特定情况,如果格式确实是不变的,我会选择Aleks G's approach。
答案 2 :(得分:1)
使用以下内容:
Pattern pattern = Pattern.compile("^[a-zA-Z]+0*(\\d+)-[a-zA-Z]+0*(\\d+).*");
Matcher matcher = pattern.matcher(st);
if (matcher.matches()) {
int num1 = Integer.parseInt(matcher.group(1));
int num2 = Integer.parseInt(matcher.group(2));
System.out.println(num1+" - "+num2);
}
答案 3 :(得分:1)
为什么第二个代码只返回第一个数字? (XXX)并且未命中 第二个?
如果你看一下你的模式 - "^[a-zA-Z]+([0-9]+).*"
,它的开头就有一个锚caret - ^
。这意味着,您的模式只会在字符串的开头搜索。这就是为什么你只得到SPXXX
的第一个数字,它出现在字符串"SPXXX-SPYYY"
的开头,而不是模式SPYYY
,因为它不在开头,因此不会匹配。
您可以删除caret (^)
,但最后不要.*
,因为您使用的是Matcher#find()
方法。
Pattern pattern = Pattern.compile("[a-zA-Z]+([0-9]+)");
但是,鉴于您的字符串将始终采用相同的格式,您甚至可以使用更简单的模式:
Pattern pattern = Pattern.compile("\\d+");
从 matcher 获取 group 1 。
为此目的,哪些代码更好?
我会采用第二种方法。拆分字符串可能无法始终工作,并且随着字符串的增长而变得复杂。当你真的想要在一些分隔符上拆分字符串时,你应该只使用split
。在这种情况下,您不希望拆分字符串,而是想要提取特定模式。第二种方法是要走的路。
答案 4 :(得分:1)
定义类似Pattern.compile("[a-zA-Z]+([0-9]+)");
对于示例字符串,matcher
与循环的两次迭代匹配SPXXX
和SPYYY
。
group(1)
分别为这两种情况返回XXX
和YYY
。