使用正则表达式添加前导零

时间:2010-04-17 16:14:41

标签: regex language-agnostic

我想在字符串的所有数字中添加一定数量的前导零(最多3个)。例如:

输入:/2009/5/song 01 of 12

输出:/2009/0005/song 0001 of 0012

使用正则表达式执行此操作的最佳方法是什么?

修改

我选择了第一个正确答案。但是,所有答案都值得一读。

12 个答案:

答案 0 :(得分:29)

Perl:

s/([0-9]+)/sprintf('%04d',$1)/ge;

答案 1 :(得分:5)

使用支持回调的内容,以便处理匹配:

>>> r=re.compile(r'(?:^|(?<=[^0-9]))([0-9]{1,3})(?=$|[^0-9])')
>>> r.sub(lambda x: '%04d' % (int(x.group(1)),), 'dfbg345gf345', sys.maxint)
'dfbg0345gf0345'
>>> r.sub(lambda x: '%04d' % (int(x.group(1)),), '1x11x111x', sys.maxint)
'0001x0011x0111x'
>>> r.sub(lambda x: '%04d' % (int(x.group(1)),), 'x1x11x111x', sys.maxint)
'x0001x0011x0111x'

答案 2 :(得分:2)

样本:

>>> re.sub("(?<!\d)0*(\d{1,3})(?!\d)","000\\1","/2009/5/song 01 of 3")
'/2009/0005/song 0001 of 0003'

注意:

  • 目前仅适用于数字1 - 9
  • 尚未经过考验

我现在不能想到没有使用回调的单一正则表达式*(可能有办法实现)。

这里有两个正则表达式来处理:

>>> x = "1/2009/5/song 01 of 3 10 100 010 120 1200 abcd"
>>>
>>> x = re.sub("(?<!\d)0*(\d{1,3})(?!\d)","000\\1",x)
#'0001/2009/0005/song 0001 of 0003 00010 000100 00010 000120 1200 abcd'
>>>
>>> re.sub("0+(\d{4})(?!\d)","\\1",x) #strip extra leading zeroes
'0001/2009/0005/song 0001 of 0003 0010 0100 0010 0120 1200 abcd'

答案 3 :(得分:1)

另一种方法:

>>> x
'/2009/5/song 01 of 12'
>>> ''.join([i.isdigit() and i.zfill(4) or i for i in re.split("(?<!\d)(\d+)(?!\d)",x)])
'/2009/0005/song 0001 of 0012'
>>>

或者:

>>> x
'/2009/5/song 01 of 12'
>>> r=re.split("(?<!\d)(\d+)(?!\d)",x)
>>> ''.join(a+b.zfill(4) for a,b in zip(r[::2],r[1::2]))
'/2009/0005/song 0001 of 0012'

答案 4 :(得分:1)

如果正则表达式实现不支持后视和/或前瞻断言,您也可以使用此正则表达式:

(^|\D)\d{1,3}(\D|$)

并将匹配替换为$1 + padLeft($2, 4, "0") + $3,其中$1与第一组匹配,padLeft(str, length, padding)str前缀为padding的函数,直到已达到length个长度。

答案 5 :(得分:1)

<warning>这假定学术兴趣,当然你应该使用回调来清楚正确地做到</warning>

我可以滥用正则表达式来获得两个前导零(.NET风格):

s = Regex.Replace(s, @".(?=\b\d\b)|(?=\b\d{1,2}\b)", "$&0");

如果字符串的开头有一个数字,它就不起作用。这通过匹配数字之前的0宽度或数字之前的字符,并将其替换为0来实现。

我没有运气将它扩展到三个前导零,当然不会更多。

答案 6 :(得分:1)

使用c#

string result = Regex.Replace(input, @"\d+", me =>
{
    return int.Parse(me.Value).ToString("0000");
});

答案 7 :(得分:0)

这是一个没有回调或递归的Perl解决方案。它确实使用Perl正则表达式执行代码扩展代替直接替换(e开关),但这很容易扩展到缺少该构造的其他语言。

#!/usr/bin/perl

while (<DATA>) {
   chomp;
   print "string:\t\t\t$_\n";
# uncomment if you care about 0000000 case:
#   s/(^|[^\d])0+([\d])/\1\2/g;
#   print "now no leading zeros:\t$_\n";    
   s/(^|[^\d]{1,3})([\d]{1,3})($|[^\d]{1,3})/sprintf "%s%04i%s",$1,$i=$2,$3/ge;
   print "up to 3 leading zeros:\t$_\n";
}
print "\n";

__DATA__
/2009/5/song 01 of 12
/2010/10/song 50 of 99
/99/0/song 1 of 1000
1
01
001
0001
/001/
"02"
0000000000

输出:

string:                /2009/5/song 01 of 12
up to 3 leading zeros:  /2009/0005/song 0001 of 0012
string:                /2010/10/song 50 of 99
up to 3 leading zeros:  /2010/0010/song 0050 of 0099
string:                /99/0/song 1 of 1000
up to 3 leading zeros:  /0099/0/song 0001 of 1000
string:                1
up to 3 leading zeros:  0001
string:                01
up to 3 leading zeros:  0001
string:                001
up to 3 leading zeros:  0001
string:                0001
up to 3 leading zeros:  0001
string:                /001/
up to 3 leading zeros:  /0001/
string:                "02"
up to 3 leading zeros:  "0002"
string:                0000000000
up to 3 leading zeros:  0000000000

答案 8 :(得分:0)

在Xcode中合并:

targetName=[NSString stringWithFormat:@"%05d",number];

为123号提供00123

答案 9 :(得分:0)

有效的Scala程序将所有n个数字组替换为4. $$转义结束字符$,因为我们使用的是StringContext(以s为前缀的字符串)。 / p>

  (f/:(1 to 3)){case (res,i) =>
     res.replaceAll(s"""(?<=[^\\d]|^)(\\d$i)(?=[^\\d]|$$)""", "0"*(4-i)+"$1")
  }

答案 10 :(得分:0)

C#版本

        string input = "/2009/5/song 01 of 12";
        string regExPattern = @"(\/\d{4}\/)(\d+)(\/song\s+)(\d+)(\s+of\s+)(\d+)";
        string output = Regex.Replace(input, regExPattern, callback =>
        {
            string yearPrefix = callback.Groups[1].Value;
            string digit1 = int.Parse(callback.Groups[2].Value).ToString("0000");
            string songText = callback.Groups[3].Value;
            string digit2 = int.Parse(callback.Groups[4].Value).ToString("0000");
            string ofText = callback.Groups[5].Value;
            string digit3 = int.Parse(callback.Groups[6].Value).ToString("0000");
            return $"{yearPrefix}{digit1}{songText}{digit2}{ofText}{digit3}";
        });

答案 11 :(得分:0)

原则:两次替换,首先在第二次删除最后x个位置时在前面添加零。这适用于我在 SQL 中解决此问题的方法。我解决的问题的解决方案。

示例: REGEXP_REPLACE(REGEXP_REPLACE(version,'.([0-9][.][0-9][.][0-9]).. ','\1.00000\2'),'([0-9][.][0-9][.][0-9][.]).* (.....$)','\1\2'),'.','')

这段代码使值 1.1.1.1 => 1.1.1.00001