соответствие многострочного присваивания переменной make-строки с регулярным выражением Python - PullRequest
2 голосов
/ 08 июля 2011

Я пытаюсь извлечь из многострочной переменной make-line присвоение многострочного значения. Следующий тестовый пример не может найти совпадение во входной строке, и я должен признаться, что я не понимаю, почему. Помощь в создании этого примера кода, напечатанного "a \ b" на stdout, была бы очень кстати.

#!/usr/bin/env python                                                                                                 

def test():
    s = r"""                                                                                                          
FOO=a \                                                                                                               
  b                                                                                                                   
"""
    import re
    print type(s),s
    regex = re.compile(r'^FOO=(.+)(?<!\\)$', re.M)
    m = regex.search(s)
    print m.group(1)

if __name__ == '__main__':
    test()

Ответы [ 4 ]

2 голосов
/ 08 июля 2011

re.M означает re.MULTILINE, но это не касается символики точки, это касается символики ^ и $

Вам нужно указать re.DOTALL, чтобы точка могла совпадать даже с '\ n'

def test():
    s = r"""    

FOO=a \    

  b

  """
    import re
    print repr(s)
    print '---------------------'
    regex = re.compile(r'^FOO=(.+)(?<!\\)$', re.M)
    print regex.search(s).group(1)
    print '---------------------'
    regex = re.compile(r'^FOO=(.+)(?<!\\)$', re.M|re.DOTALL)
    print regex.search(s).group(1)

test()

результат

'    \n\nFOO=a \\    \n\n  b\n\n  '
---------------------
a \    
-----
'a \\    '
---------------------
a \    

  b


-----
'a \\    \n\n  b\n\n  '
1 голос
/ 08 июля 2011

Ваша проблема в том, что . не соответствует символу новой строки по умолчанию.Если вы включите модификатор Dotall, он будет работать.

regex = re.compile(r'^FOO=(.+)(?<!\\)$', re.M | re.S)

Вы сделаете это, используя re.S

В результате вы получите

a \

 b

Ваш шаблон просто соответствует шаблону, включая разрывы строк.

Я не уверен, чего вы хотите достичь с помощью многострочного модификатора re.M.^ и $ соответствуют началу / концу строки.Я полагаю, вы можете удалить его.

Я также не уверен, чего вы хотите добиться своим негативным взглядом (?<!\\), думаю, вам следует уточнить ожидаемый результат.(Вы хотите удалить символы новой строки в a \ b?)

0 голосов
/ 08 июля 2011

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

Но обратные слэши могут использоваться и для экранирования других персонажей, включая обратные слэши. Если значение заканчивается обратной косой чертой, оно будет отображаться как две обратной косой черты в make-файле. Взгляд в вашем регулярном выражении «увидит» второе и неправильно воспримет его как продолжение строки.

Если вы думаете добавить еще один вид сзади, чтобы увидеть, не произошла ли обратная косая черта, позвольте мне остановить вас сейчас. Это многократно хешировалось, и подход за кадром нельзя заставить работать. То, что вы хотите, это что-то вроде этого:

regex = re.compile(r'^FOO=([^\n\\]*(?:\\.[^\n\\]*)*)$', re.M | re.S)

См. Это в действии на ideone

Первый [^\n\\]* потребляет столько символов без перевода строки, без обратной косой черты, сколько может, затем передает управление следующей части. Если конец строки не был достигнут, он пытается сопоставить обратную косую черту, за которой следует любой символ (включая перевод строки, благодаря модификатору re.S), за которым следуют мои более «нормальные» символы. Так продолжается в цикле до тех пор, пока (при условии, что вход действителен), он не попадет в неэкранированный перевод строки или в конец ввода.

Хотя это модификатор re.S, который позволяет точкам соответствовать новые строки, модификатор re.M также необходим; это то, что позволяет ^ соответствовать началу строки, а $ соответствует концу строки, как объяснила @stema.

0 голосов
/ 08 июля 2011

Я придумал это:

^FOO=((([^\\]*\\\n)*)[^\n]+)

предполагается, что за обратной косой чертой нет пробелов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...