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

309

我在stackoverflow上看到了有关如何在数字前面添加零的问题。但是没有关于反过来的问题!

你们能否建议我如何删除字母数字文本中的前导零?是否存在内置的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
21个回答

761

正则表达式是解决问题的最佳工具,其应该根据问题的规范来确定。以下代码可以删除前导零,但如果有必要则保留一个(即它不会将"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+(?!$)", "") + "]");
}

另请参见


38
谢谢。你进行了无情的测试 ;) 很棒!! 点赞为测试加1分。 - jai
5
@Greg:这个问题是关于Java而不是JavaScript的。自Java SE 1.4版本以来,它就拥有了方法String.replaceFirst() - Jonik
7
在s.replaceFirst("^0+(?!$)", "")中添加trim() (即s.trim().replaceFirst("^0+(?!$)", "")) 可以帮助去掉填充的空格! - AVA
2
正则表达式对于这么简单的任务来说有点昂贵,不是吗? - demongolem
20
这在 Kotlin 中无法工作,你需要明确指定正则表达式 .replaceFirst("^0+(?!$)".toRegex(), "") - mkabatek
显示剩余6条评论

169

1
这个是否与仅为“0”有问题?@Hamilton Rodrigues - PhoonOne
4
如果仅将其用于“0”,它会返回“”。因此,如果这不是所需的效果,请小心。 - dARKpRINCE
点赞,因为它适用于所提问的用例。对我也有帮助,提供了一个快速解决方案。谢谢! - Gabriel Amazonas Mesquita

40

那么使用正则表达式的方式如何:

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";

8
只有数字“0”存在问题。 - Vadzim

40

如果您正在使用 Kotlin,则只需要这段代码:

yourString.trimStart('0')

30

一种清晰的方式,不需要使用正则表达式或任何外部库。

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
@JohnFowler 感谢你的发现,经过2年多的修复。 - magiccrafter
1
如果循环仅找到零,则该方法需要在末尾返回。返回“”; 或者如果您想要至少一个零,则返回“0”。 - slipperyseal
@slipperyseal 我把它留开了,这样你就可以根据自己的需求进行更改,但由于人们倾向于复制/粘贴,始终具有默认行为并不是一个坏主意。感谢您的评论。 - magiccrafter

15

为了补充thelost的Apache Commons答案:使用guava-libraries(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

14
你可以这样做: String s = Integer.valueOf("0001007").toString(); (将字符串转为整数并转回字符串)

7
无法处理字母数字混合。 - slaman
1
如果值太大,例如“00087878787878787878”,超出了整数的范围,它也会失败。 - Shashank Garg

6
请使用以下内容:
String x = "00123".replaceAll("^0*", ""); // -> 123

5

使用Apache Commons StringUtils类:

StringUtils.strip(String str, String stripChars);

5
警告!这将去除前导和结尾的零,可能不是您想要的。 - Jens Bannmann
24
您可以使用StringUtils.stripStart()函数仅去除前导零。 - Josh Rosen

2

正则表达式是解决这个问题的好方法,一些答案提出了这个建议。如果您不想使用正则表达式,则可以使用以下代码:

String s = "00a0a121";

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

这可能会创建很多String...使用魔法制造者方法代替。 - AxelH

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接