2012-01-19 2 views

ответ

24

Вы можете передать функцию в re.sub(), что позволит вам сделать это, вот пример:

def upper_repl(match): 
    return 'GOO' + match.group(1).upper() + 'GAR' 

И пример его использования:

>>> re.sub(r'foo([a-z]+)bar', upper_repl, 'foobazbar') 
'GOOBAZGAR' 
+2

Я полагаю, что это должно будет сделать, хотя это ужасно сложно, учитывая. –

+0

Brillant! Иногда нам нужно просто RTFD полностью ... – Zulu

3

Вы могли бы использовать некоторые вариации этого:

s = 'foohellobar' 
def replfunc(m): 
    return m.groups()[0]+m.groups()[1].upper()+m.groups()[2] 
re.sub('(foo)([a-z]+)(bar)',replfunc,s) 

дает выход:

'fooHELLObar' 
+0

Это правильный ответ. – dmvianna

5

Вы имеете в виду что-то вроде этого?

>>>x = "foo spam bar" 
>>>re.sub(r'foo ([a-z]+) bar', lambda match: r'foo {} bar'.format(match.group(1).upper()), x) 
'foo SPAM bar' 

Для справки, вот строка документации из re.sub (курсив мой).

Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement repl. repl can be either a string or a callable; if a string, backslash escapes in it are processed. If it is a callable, it's passed the match object and must return a replacement string to be used.

+0

Traceback (последний последний звонок): Файл «», строка 1, in Файл «/usr/lib64/python2.6/re.py», строка 151, в sub return _compile (pattern, 0) .sub (repl, string, count) Файл «», строка 1, in ValueError: имя поля нулевой длины в формате – Lobo

2

Если у вас уже есть строки замены (шаблон), вы не можете быть заинтересованы в обмен его с многословием m.group(1)+...+m.group(2)+...+m.group(3) ... Иногда это приятно иметь опрятную немного строки.

Вы можете использовать expand() функцию, MatchObject «s, чтобы оценить шаблон для матча в той же манере, как sub(), что позволяет сохранить как можно больше исходного шаблона, как это возможно. Вы можете использовать upper на соответствующих рисунках.

re.sub(r'foo([a-z]+)bar', lambda m: 'GOO' + m.expand('\1GAR').upper()) 

Хотя это не было бы особенно полезно в приведенном выше примере, и пока он не помогает сложных обстоятельствах, это может быть более удобным для более длинных выражений с большим числом захваченных групп, таких как МАС-адрес Цензурирование регулярного выражения, где вы просто хотите, чтобы полная замена была капитализирована или нет.

1

Для тех, встретив это на гугле ...

Вы также можете использовать re.sub, чтобы соответствовать повторяющиеся узоры. Например, вы можете преобразовать строку с пробелами в camelCase:

def to_camelcase(string): 
    string = string[0].lower() + string[1:] # lowercase first 
    return re.sub(
    r'[\s]+(?P<first>[a-z])',    # match spaces followed by \w 
    lambda m: m.group('first').upper(), # get following \w and upper() 
    string) 

to_camelcase('String to convert')   # --> stringToConvert 
Смежные вопросы