2015-07-12 2 views
2

Если мой рисунок группа не содержит символ новой строки (\n) характер, все работает отлично:Regex замена не работает, если группа содержит флаг новой строки

contents = b''' 
xdlg::xdlg(x_app* pApp, CWnd* pParent) 
    : customized_dlg((UINT)0, pParent, pApp) 
''' 
pattern = rb'(\w+)(::)(\1)' 
res = re.search(pattern, contents, re.DOTALL | re.MULTILINE) 
if None != res: 
    print(res.groups()) # output is: (b'xdlg', b'::', b'xdlg') 
sub = rb"\1--\2--\1" 
contents = re.sub(pattern, sub, contents, re.DOTALL | re.MULTILINE) 
print(contents) # output is b'\nxdlg--::--xdlg...(to save space, unchanged string is ignored) 

, но если я изменю pattern содержать '\n', re.sub терпит неудачу изменить contents:

pattern = rb'(\w+)(::)(\1)(.*\n*:\n*.*)(\(UINT\)0)' 
res = re.search(pattern, contents, re.DOTALL | re.MULTILINE) 
if None != res: 
    print(res.groups()) # output is (b'xdlg', b'::', b'xdlg', b'(x_app* pApp, CWnd* pParent)\n\t: customized_dlg(', b'(UINT)0') 
sub = rb"\1--\2--\1" 
contents = re.sub(pattern, sub, contents, re.DOTALL | re.MULTILINE) 
print(contents) # the output doesn't change anything! 

что я здесь делаю неправильно?


(я использую Python 3.4.2)

+1

Почему вы используете '. * \ N *: \ n * \. *'? С флагом 're.DOTALL' вы можете просто написать'. *:. * 'Или даже лучше' [^:] *: [^ (] * '(что, вероятно, было бы более эффективным). – Bakuriu

+0

' (. * \ n *: \ n *. *) 'Это не соответствует' \ n: '. Вы пропускаете пробелы/вкладки перед': ' – dhke

+0

@dhke, по сути, '. *' не может пропустить ничего с 're.DOTALL' –

ответ

4

Я рекомендую прохождение регулярных выражения флагов в качестве именованного аргумента при использовании re модуля. Here's the sub() method signature from the docs.

re.sub(pattern, repl, string[, count, flags]) 

В своем коде, ваши «флаги» будет интерпретироваться как подсчитывать вместо этого, потому что модуль флаги повторно в действительности являются целыми числами и re.DOTALL | re.MULTILINE == 16.

Ваш код должен быть таким: (re.MULTILINE не имеет никакого эффекта для этого конкретного шаблона регулярного выражения)

contents = re.sub(pattern, sub, contents, flags=re.DOTALL) 

Если вы не использовали именованные аргументы, вам необходимо пройти в count, а также. 0 означает, что все экземпляры будут заменены.

contents = re.sub(pattern, sub, contents, 0, re.DOTALL) 
+0

нет, это не ключ, я проверил его только с re.DOTALL, результат тот же самый с моим –

+0

Повторите мой ответ еще раз: 're.DOTALL' не имеет значения. Аргументы метода - это то, что вы сделали неправильно.' Flags' на самом деле является целым числом, поэтому он будет интерпретироваться как 'count', если вы передадите его как 4-й аргумент. –

+2

Я считаю, что вы должны также упомянуть, что регулярное выражение, которое он использует, довольно неэффективно и сложнее, чем должно быть ... – Bakuriu

Смежные вопросы