2016-07-28 11 views
0

Рассмотрим текст ниже:Почему регулярное выражение (. *? (?: *? N)) захватывает новые строки?

foobar¬ 
nextline 

регулярное выражение (.*?(?: *?\n)) соответствует foobar¬ где ¬ обозначает символ новой строки \ п.

Почему регулярное выражение соответствует этому? не следует ли исключать эту группу?

Протестировано на Regex101 для диалекта питона.

+2

Группа не-захвата не группируется, но соответствует. – Maroun

+0

Вы запросили механизм регулярного выражения, чтобы он соответствовал ему \ n. –

+0

'\ n' находится в группе, не связанной с захватом, но почему она захвачена? –

ответ

6

«Non-отлов группа» относится к тому факту, что соответствует в этой группе не будет доступен в виде отдельных групп в результате матча OBJE кт. Например:

>>> re.search('(foo)(bar)', 'foobarbaz').groups() 
('foo', 'bar') 
>>> re.search('(foo)(?:bar)', 'foobarbaz').groups() 
('foo',) 

Однако, все, что является частью выражения соответствует и как таковой появляется в результате матча (группа 0 показывает весь матч):

>>> re.search('(foo)(bar)', 'foobarbaz').group(0) 
'foobar' 
>>> re.search('(foo)(?:bar)', 'foobarbaz').group(0) 
'foobar' 

Если вы дон «т хочет, чтобы соответствовать той части, но все еще хочет, чтобы убедиться, что там, вы можете использовать выражение опережения:

>>> re.search('(foo)(?=bar)', 'foobarbaz') 
<_sre.SRE_Match object; span=(0, 3), match='foo'> 
>>> re.search('(foo)(?=bar)', 'foobaz') 
None 

Так что в вашем случае, вы могли бы использование (.*?(?= *?\n)).

+0

Это имеет смысл! Спасибо –

+0

Сам взгляд не будет соответствовать чему-либо, он просто удостоверится, что то, что внутри, появилось после выражения. Поэтому, если вы хотите совместить как 'foo', так и' bar', вам действительно нужно включить новую строку, которая находится между ними в матче. Поскольку выражение не будет соответствовать новой строке, совпадение будет расширяться прямо перед ним, поэтому будет сопоставлено только 'foo'. – poke

2

\n захвачен, потому что без захвата группа внутри Захват группы:

>>> s = 'foobar\nnextline' 
>>> re.search(r'(.*?(?: *?\n))', s).groups() 
('foobar\n',) 

Если вы не хотите этого, поместите, не захватив группу вне из захвата одного :

>>> re.search(r'(.*?)(?: *?\n)', s).groups() 
('foobar',) 
+0

Вы даже можете избавиться от группы, не захватывающей: 're.search (r '(. *?) *? \ n', s) .groups () 'должен дать тот же результат. – Tensibai

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

  • Нет связанных вопросов^_^