如何从字母数字文本中删除前导零?


228

我在SO中看到了有关如何在零前面加上前缀的问题。但不是相反!

你们能建议我如何删除字母数字文本中的前导零吗?是否有内置的API,或者我需要编写一种方法来修剪前导零?

例:

01234 converts to 1234
0001234a converts to 1234a
001234-a converts to 1234-a
101234 remains as 101234
2509398 remains as 2509398
123z remains as 123z
000002829839 converts to 2829839

Answers:


617

正则表达式是完成这项工作的最佳工具。它应该是什么取决于问题规范。下面的代码删除前导零,但在必要时留下一个(即,它不仅会变成"0"空白字符串)。

s.replaceFirst("^0+(?!$)", "")

^主播将确保该0+所匹配是在输入的开始。该(?!$)负前瞻确保不是整个字符串匹配。

测试线束:

String[] in = {
    "01234",         // "[1234]"
    "0001234a",      // "[1234a]"
    "101234",        // "[101234]"
    "000002829839",  // "[2829839]"
    "0",             // "[0]"
    "0000000",       // "[0]"
    "0000009",       // "[9]"
    "000000z",       // "[z]"
    "000000.z",      // "[.z]"
};
for (String s : in) {
    System.out.println("[" + s.replaceFirst("^0+(?!$)", "") + "]");
}

也可以看看


21
谢谢。而且您已经进行了无情的测试;)太棒了!+1进行测试。
JAI

4
@Greg:这个问题是关于Java的,而不是JavaScript。从1.4版开始,Java SE就使用了String.replaceFirst()方法。
约尼克

5
将trim()添加到s.replaceFirst(“ ^ 0 +(?!$)”,“”)(即s.trim()。replaceFirst(“ ^ 0 +(?!$)”,“”)删除填充空间!
AVA 2014年

2
正则表达式对于这样一个简单的任务不是有点贵吗?
demongolem

5
这在Kotlin中不起作用,您需要明确介绍正则表达式.replaceFirst("^0+(?!$)".toRegex(), "")
mkabatek

100

您可以像这样从Apache Commons Lang使用StringUtils类:

StringUtils.stripStart(yourString,"0");

这是否仅与“ 0”有关?@Hamilton Rodrigues
PhoonOne 2015年

2
如果仅在“ 0”上使用它,则返回“”。因此,请注意这是否不是所需的效果。
dARKpRINCE,2015年

赞成,因为它适用于所问问题中的用例。在这里也为我提供了快速解决方案。谢谢!
加百利·亚马逊·梅斯基塔

32

正则表达式的方式如何:

String s = "001234-a";
s = s.replaceFirst ("^0*", "");

^字符串开头的锚点(我从上下文假设这里的字符串不是多行的,否则您可能需要查找输入\A的开始而不是行的开头)。该0*方法零个或多个0字符(你可以使用0+为好)。在replaceFirst刚刚替换所有那些0在一开始什么也没有的字符。

并且,如果像Vadzim一样,您对前导零的定义不包括将"0"(或"000"类似字符串)变成空字符串(足够合理的期望),则在必要时将其放回原处:

String s = "00000000";
s = s.replaceFirst ("^0*", "");
if (s.isEmpty()) s = "0";

6
仅“ 0”有问题。
Vadzim 2012年

23

一种无需regExp和任何外部库的清晰方法。

public static String trimLeadingZeros(String source) {
    for (int i = 0; i < source.length(); ++i) {
        char c = source.charAt(i);
        if (c != '0') {
            return source.substring(i);
        }
    }
    return ""; // or return "0";
}

1
尽管您对空间的检查不符合问题,但是我认为您的答案执行最快。
John Fowler

为抓,固定后2年以上@JohnFowler 10倍
magiccrafter

1
如果循环仅找到零,则该方法需要在最后返回。返回“”;或返回“ 0”;如果你想至少一个零
slipperyseal

@slipperyseal我将其保留为打开状态,以便您可以根据自己的需要进行更改,但是由于人们倾向于复制/粘贴,因此始终具有默认行为并不是一个坏主意。感谢您的评论
magiccrafter

14

要配合失落者的Apache Commons答案:使用guava库(我认为Google的通用Java实用程序库现在应该在任何非平凡的Java项目的类路径中),将使用CharMatcher

CharMatcher.is('0').trimLeadingFrom(inputString);

+1,对于使用Guava的任何项目都是正确的答案。(现在2012年是应该意味着几乎所有的Java项目。)
Jonik

1
@Cowan这是否仅与“ 0”有关?将CharMatcher.is('0')。trimLeadingFrom(“ 0”); 返回“ 0”还是空字符串?
PhoonOne

@PhoonOne:我刚刚测试过;它返回空字符串。
Stephan202 '16

10

如果您使用的是Kotlin,则这是您唯一需要的代码:

yourString.trimStart('0')

5

您可以这样做: String s = Integer.valueOf("0001007").toString();


2
无法处理字母数字。
slaman

4

使用Apache Commons StringUtils类:

StringUtils.strip(String str, String stripChars);

2
警告!这将去除开头和结尾的零,这可能不是您想要的。
Jens Bannmann

18
您可以使用StringUtils.stripStart()仅去除前导零。
乔什·罗森


2

将Regexp与组配合使用:

Pattern pattern = Pattern.compile("(0*)(.*)");
String result = "";
Matcher matcher = pattern.matcher(content);
if (matcher.matches())
{
      // first group contains 0, second group the remaining characters
      // 000abcd - > 000, abcd
      result = matcher.group(2);
}

return result;

2

使用正则表达式作为一些答案表明,这是一个很好的方法。如果您不想使用正则表达式,则可以使用以下代码:

String s = "00a0a121";

while(s.length()>0 && s.charAt(0)=='0')
{
   s = s.substring(1); 
}

这可能会产生很多String...使用magiccrafter方法代替。
AxelH

1

我认为这样做很容易。您可以从头开始遍历字符串,然后删除零,直到找到一个不为零的字符。

int lastLeadZeroIndex = 0;
for (int i = 0; i < str.length(); i++) {
  char c = str.charAt(i);
  if (c == '0') {
    lastLeadZeroIndex = i;
  } else {
    break;
  }
}

str = str.subString(lastLeadZeroIndex+1, str.length());

1

如果您(像我一样)需要删除字符串中每个“单词”的所有前导零,则可以修改@polygenelubricants对以下内容的回答:

String s = "003 d0g 00ss 00 0 00";
s.replaceAll("\\b0+(?!\\b)", "");

结果是:

3 d0g ss 0 0 0

1

如果不使用Regexsubstring()功能String效率低下-

public static String removeZero(String str){
        StringBuffer sb = new StringBuffer(str);
        while (sb.length()>1 && sb.charAt(0) == '0')
            sb.deleteCharAt(0);
        return sb.toString();  // return in String
    }

0

您可以用正则表达式替换"^0*(.*)""$1"


1
我在这里看到的唯一问题是,这可能会将孤立的零“ 0”替换为空白。
Dilipkumar J 2012年

0
       String s="0000000000046457657772752256266542=56256010000085100000";      
    String removeString="";

    for(int i =0;i<s.length();i++){
      if(s.charAt(i)=='0')
        removeString=removeString+"0";
      else 
        break;
    }

    System.out.println("original string - "+s);

    System.out.println("after removing 0's -"+s.replaceFirst(removeString,""));

0

如果您不想使用正则表达式或外部库。您可以使用“用于”:

String input="0000008008451"
String output = input.trim();
for( ;output.length() > 1 && output.charAt(0) == '0'; output = output.substring(1));

System.out.println(output);//8008451

String在此循环中生成的太多…如果有1000 0...
AxelH

0

我进行了一些基准测试,发现(到目前为止)最快的方法是这种解决方案:

    private static String removeLeadingZeros(String s) {
      try {
          Integer intVal = Integer.parseInt(s);
          s = intVal.toString();
      } catch (Exception ex) {
          // whatever
      }
      return s;
    }

特别是正则表达式在长迭代中非常慢。(我需要找出批处理作业的最快方法。)


-2

那只搜索第一个非零字符呢?

[1-9]\d+

此正则表达式查找1到9之间的第一个数字,后跟任意数量的数字,因此对于“ 00012345”,它返回“ 12345”。它可以轻松地适用于字母数字字符串。


此后也将不允许零。
Nishant Dongare
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.