【问题标题】:How can I get the last integer "56" from String like ra12ke43sh56?如何从像 ra12ke43sh56 这样的字符串中获取最后一个整数“56”?
【发布时间】:2011-03-06 05:14:53
【问题描述】:

如何从 ra12ke43sh56 这样的字符串中获取最后一个整数“56”?

我必须将下一个值修改为 ra12ke43sh57 所以我想得到最后一个整数值。

【问题讨论】:

    标签: java


    【解决方案1】:
    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)

    【讨论】:

    • 为什么不用 '[0-9]+$' 将 RE 固定到末尾?
    • 谢谢,但它适用于最后一位数字 abc88,但当它出现 abc9999 时,它将不起作用
    • @nicerobot - 事实上,我更新了我的答案@Rakesh - 我没有得到你的评论。它也适用于 abc9999。
    【解决方案2】:

    也许这就是你想要的 (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 : 宽度为 5
        • d:十进制整数转换

    相关问题

    环顾四周:

    参考文献

    【讨论】:

    • 你显然爱上了环视 :) 但在这种情况下,简单的 "(\\d+)$" 也可以——只需直接捕获 id,而不是匹配id 并在那里拆分字符串。
    【解决方案3】:

    不是一个答案,只是提到这个“明显”的正则表达式(如上面发布的)在最坏的情况下有一个令人讨厌的二次行为(我很确定你没有处理这种退化的情况,但是它本身就很有趣)。

    这是我准备的一个小图表: alt text http://img517.imageshack.us/img517/1158/imageerp.jpg

    我使用了“111..1111a2”形式的字符串 J 出现了“1”。

    表现不佳的原因很明显:matcher一直看到1s并且高兴地认为它会成功,只有当它找到a接近尾声时它才发现a$不匹配,所以它一直往回走,从第二个字符开始。

    最初我认为所有格量词在这里会有所帮助,但它看起来并不简单。即使我写了\d++,如果我调用matcher.find(),它仍然会尝试匹配模式从每个索引开始,即外部循环不会从先前的占有失败中得到任何提示量词。 (注意这个问题不会影响 Matcher.matches() 因为它只尝试在单个索引处匹配,即开始)。

    在这个特殊的问题中,为了避免这种行为,我们必须反转字符串并使用简单的^\\d+ 模式进行搜索,或者向后迭代字符并进行手动匹配。

    【讨论】:

    【解决方案4】:
    String result = str.substring(str.replaceAll("[0-9]+$","").length());
    

    如果strra12ke43sh56,则分解它:

    str.replaceAll("[0-9]+$","") 
    

    返回除最后一组数字之外的所有数字,即 ra12ke43sh

    substring 在主字符串中 this 的长度只返回结束数字,即 56。

    【讨论】:

      【解决方案5】:
        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();
      }
      

      【讨论】:

        【解决方案6】:
        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());
        
        }
        

        }

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-04-16
          • 2015-06-27
          • 2011-07-07
          • 2011-08-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多