Как подобрать подстрочные группы и переменные в Python

новый для python. Это, наверное, просто, но я не нашел ответа.

rndStr = "20101215"
rndStr2 = "20101216"
str = "Looking at dates between 20110316 and 20110317"
outstr = re.sub("(.+)([0-9]{8})(.+)([0-9]{8})",r'\1'+rndStr+r'\2'+rndStr2,str)

Результат, который я ищу, это:

Looking at dates between 20101215 and 20101216

Но вместо этого я получаю:

P101215101216

Значения двух rndStr не имеют большого значения. Предположим, что он случайный или взятый из пользовательского ввода (я ставил статические vals здесь, чтобы он был простым). Спасибо за любую помощь.

Ответ 1

Ваши обратные ссылки неоднозначны. Ваша строка замены станет

\120101215\220101216

который представляет собой два довольно больших числа для обратного обращения:)

Чтобы решить эту проблему, используйте этот синтаксис:

r'\g<1>'+rndStr+r'\g<2>'+rndStr2 

У вас также слишком много наборов круглых скобок (или "скобок", если вы говорите по-английски, как я:) - вам не нужны круглые скобки вокруг частей [0-9]{8}, которые вы не обращаете на обратную связь:

re.sub("(.+)[0-9]{8}(.+)[0-9]{8}",...

должно быть достаточно.

(И, как уже отмечалось в другом месте, не используйте str в качестве имени переменной. Если вы не хотите тратить возрасты на отладку, почему str.replace() больше не работает. Не то, чтобы я когда-либо делал это однажды... noooo.:)

поэтому все это становится:

import re
rndStr = "20101215"
rndStr2 = "20101216"
s = "Looking at dates between 20110316 and 20110317"
outstr = re.sub("(.+)[0-9]{8}(.+)[0-9]{8}", r'\g<1>'+rndStr+r'\g<2>'+rndStr2, s) 
print outstr

Производство:

Looking at dates between 20101215 and 20101216

Ответ 2

Обратите внимание, если вы измените значение rndStr или rndStr2 на текст (например, "abc" ), а не на цифры, вы получите что-то ближе к ожидаемому результату?

В вашем выражении re.sub у вас есть r'\1'+rndStr+... Он объединяется в '\1'+'20101215', который затем пытается ссылаться на обратную ссылку \120101215, которая, вероятно, не та, что вы намеревались...

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

rep1 = "20101215"
rep2 = "20101216"
st = "Looking at dates between 20110316 and 20110317"

print re.sub(r'(?P<fp>.+)[0-9]{8}(?P<lp>.+)[0-9]{8}',
            r'\g<fp>'+rep1+r'\g<lp>'+rep2,st)

Еще лучше, используйте более понятный синтаксис и проверьте возврат попытки:

m=re.search(r'(?P<fp>.+)[0-9]{8}(?P<lp>.+)[0-9]{8}',st)
if m:
    print m.group('fp')+rep1+m.group('lp')+rep2  #you could use m.group(1) too
else:
    print "no match..."

В любом случае создается желаемая строка Looking at dates between 20101215 and 20101216 .

Документы Python с именами обратных ссылок:

(?P<name>...)

Подобно обычным скобкам, но подстрока, соответствующая группе, является доступный в остальной части регулярное выражение через символическое имя группы 'name'. Имена групп должны быть действительные идентификаторы Python, и каждый имя группы должно быть определено только один раз в пределах регулярного выражения. символическая группа также является пронумерованной группы, как если бы группа не была по имени. Таким образом, группа с именем 'id' в пример ниже также можно ссылаться как пронумерованная группа 1.

Например, если шаблон (?P<id>[a-zA-Z_]\w*), группа может быть ссылается на свое имя в аргументах методы объектов соответствия, такие как m.group('id') или m.end('id'), а также по имени в регулярном выражении (используя (?P=id)) и замену текст, присвоенный .sub() (используя \g<id>).

Ответ 3

rndStr = "20101215"
rndStr2 = "20101216"
mys = "Looking at dates between {0} and {1}".format(rndStr, rndStr2)

Пожалуйста, не используйте str как имя переменной; он перезаписывает встроенный тип str.

Ответ 4

rndStr = "20101215"
rndStr2 = "20101216"

print "Looking at dates between %s and %s" %(rndStr,rndStr2)