【发布时间】:2011-03-06 05:14:53
【问题描述】:
如何从 ra12ke43sh56 这样的字符串中获取最后一个整数“56”?
我必须将下一个值修改为 ra12ke43sh57 所以我想得到最后一个整数值。
【问题讨论】:
标签: java
如何从 ra12ke43sh56 这样的字符串中获取最后一个整数“56”?
我必须将下一个值修改为 ra12ke43sh57 所以我想得到最后一个整数值。
【问题讨论】:
标签: java
StringBuilder sb = new StringBuilder();
for (int i = str.length() - 1; i >= 0; i --) {
char c = str.charAt(i);
if (Character.isDigit(c)) {
sb.insert(0, c);
} else {
break;
}
}
String result = sb.toString();
或
Pattern p = Pattern.compile("[0-9]+$");
Matcher m = p.matcher(str);
if(m.find()) {
result = m.group();
}
然后Integer.parseInt(result)
【讨论】:
也许这就是你想要的 (see also on ideone.com):
static String nextId(String id) {
String[] parts = id.split("(?=\\d+$)", 2);
final int L = parts[1].length();
final int num = Integer.parseInt(parts[1]) + 1;
return parts[0] + String.format("%0"+L+"d", num);
}
public static void main(String[] args) {
String[] tests = {
"jamesBond007", "ra12ke43sh57", "-42", "x888y999", "00000"
};
for (String test : tests) {
System.out.println(nextId(test));
}
// prints "jamesBond008", "ra12ke43sh58", "-43", "x888y1000", "00001"
}
这里有几件事在起作用:
String.split(String regex, int limit),限2个部分
parts[0] 是静态前缀,可能为空parts[1] 是字符串末尾的数字序列(?=\d+$) 匹配可以匹配 \d+$ 的位置
\d字符类+
$
String.format 保留任何前导零
%05d 这样的格式意味着:
0 : 用前导零填充5 : 宽度为 5d:十进制整数转换环顾四周:
【讨论】:
不是一个答案,只是提到这个“明显”的正则表达式(如上面发布的)在最坏的情况下有一个令人讨厌的二次行为(我很确定你没有处理这种退化的情况,但是它本身就很有趣)。
这是我准备的一个小图表: alt text http://img517.imageshack.us/img517/1158/imageerp.jpg
我使用了“111..1111a2”形式的字符串
J 出现了“1”。
表现不佳的原因很明显:matcher一直看到1s并且高兴地认为它会成功,只有当它找到a接近尾声时它才发现a与$不匹配,所以它一直往回走,从第二个字符开始。
最初我认为所有格量词在这里会有所帮助,但它看起来并不简单。即使我写了\d++,如果我调用matcher.find(),它仍然会尝试匹配模式从每个索引开始,即外部循环不会从先前的占有失败中得到任何提示量词。 (注意这个问题不会影响 Matcher.matches() 因为它只尝试在单个索引处匹配,即开始)。
在这个特殊的问题中,为了避免这种行为,我们必须反转字符串并使用简单的^\\d+ 模式进行搜索,或者向后迭代字符并进行手动匹配。
【讨论】:
String result = str.substring(str.replaceAll("[0-9]+$","").length());
如果str 是ra12ke43sh56,则分解它:
str.replaceAll("[0-9]+$","")
返回除最后一组数字之外的所有数字,即 ra12ke43sh
substring 在主字符串中 this 的长度只返回结束数字,即 56。
【讨论】:
public static String getLastDigits(String string) {
String reverseTaskId = new StringBuilder(string).reverse().toString();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < reverseTaskId.length(); i++) {
if (Character.isDigit(reverseTaskId.charAt(i))) {
sb.insert(i, reverseTaskId.charAt(i));
} else {
break;
}
}
return sb.reverse().toString();
}
【讨论】:
public class PrefixId {
public String getTransactionNumber() {
String prevNumber = "123abc321";
String incredNumber = "";
for (int i = prevNumber.length() - 1; i >= 0; i--) {
char ch = prevNumber.charAt(i);
if (incredNumber.length() > 0 && !Character.isDigit(ch)) {
break;
} else if (Character.isDigit(ch)) {
incredNumber = incredNumber + ch;
}
}
if (incredNumber.length() > 0) {
incredNumber = new StringBuffer(incredNumber).reverse().toString();
prevNumber = prevNumber.replace(incredNumber, ""
+ (Long.parseLong(incredNumber) + 1));
}
return prevNumber;
}
public static void main(String[] args) {
PrefixId prefixId = new PrefixId();
System.out.println(prefixId.getTransactionNumber());
}
}
【讨论】: