2013-02-26 78 views
0

我有固定格式的String,这将是永远:SPXXX-SPYYY.zip从固定格式的字符串中提取数字

我需要从String提取XXXYYY,但如果例如XXX是003然后我想有和不是003。 (对于YYY也是如此)。

我已经写了这两段代码:

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); 
} 
  • 为什么第二个代码只返回第一个数字? (XXX)错过了第二个?
  • 什么代码更适合此目的?
+1

你的第一个代码(分割)和第二个已经使用正则表达式! – Juvanis 2013-02-26 09:24:34

+0

@Juvanis我误解了我自己:)修正。 – Maroun 2013-02-26 09:26:39

回答

4

如果它总是相同的格式,那么为什么不使用substring

String str = "SP003-SP456.zip"; 
int xxx = Integer.parseInt(str.substring(2, 5)); 
int yyy = Integer.parseInt(str.substring(8, 11)); 

或者,如果这些XXXYYY不一定是数字,则只需添加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

为什么第二个代码只返回第一个数字? (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去。

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); 
} 
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+"); 

,并从匹配得到组1

什么样的代码更适合这个目的?

我会用第二种方法。分割字符串可能无法正常工作,并且随着字符串的增长而变得复杂。当您实际上想要在某个分隔符上拆分字符串时,应该只使用split。在这种情况下,您不想拆分字符串,而是想要提取特定的模式。第二种方法是要走的路。

1

定义这样Pattern.compile("[a-zA-Z]+([0-9]+)");

图案对于示例串matcher比赛为循环的两个迭代SPXXXSPYYY

group(1)分别返回XXXYYY