Подтвердить что ты не робот

Использование регулярного выражения для добавления ведущих нулей

Я хотел бы добавить определенное количество ведущих нулей (например, до 3) ко всем номерам строки. Например:

Вход: /2009/5/song 01 of 12

Выход: /2009/0005/song 0001 of 0012

Какой лучший способ сделать это с помощью регулярных выражений?

Edit:

Я выбрал первый правильный ответ. Тем не менее, все ответы заслуживают чтения.

4b9b3361

Ответ 1

Используйте то, что поддерживает обратный вызов, чтобы вы могли обработать соответствие:

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

В Perl:

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

Ответ 3

Образец:

>>> 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'

Ответ 4

Другой подход:

>>> 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'

Ответ 5

Если ваша реализация регулярного выражения не поддерживает утверждения look-behind и/или look-forward, вы также можете использовать это регулярное выражение:

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

И замените совпадение на $1 + padLeft($2, 4, "0") + $3, где $1 соответствует совпадению первой группы, а padLeft(str, length, padding) - это функция, которая префикс str с padding до тех пор, пока не будет достигнута длина length.

Ответ 6

<warning> Это предполагает академический интерес, конечно, вы должны использовать обратные вызовы, чтобы сделать это четко и правильно </warning>

Я могу использовать регулярные выражения, чтобы иметь два ведущих нули (вкус .NET):

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

Это не работает, если в начале строки есть число. Это работает, сопоставляя ширину 0 перед номером или символом перед номером и заменяя их 0.

Мне не повезло расширить его до трех ведущих нулей, и, конечно же, не больше.

Ответ 7

Использование c#:

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

Ответ 8

Вот решение 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

Ответ 9

Комбинировано в Xcode:

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

Дает 00123 для номера 123

Ответ 10

Действительная программа Scala для замены всех групп из n цифр на 4. $$ выполняет завершение строки char $, потому что мы используем StringContext (строка с префиксом s).

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