2015-08-28 2 views
2

Каждый элемент этого массива данных необработанного разбирается регулярное выражениеRegex/Python - почему группа захвата не захвачена в этом случае?

['\r\n\t\t\t\t\t\t', 
'Monday, Tuesday, Wednesday, Thursday, Friday, Saturday:', 
' 12:00 pm to 03:30 pm & 07:00 pm to 12:00 am\t\t\t\t\t',  
'\r\n\t\t\t\t\t\t', 
'Sunday:', 
' 12:00 pm to 03:30 pm & 07:00 pm to 12:30 am\t\t\t\t\t'] 

Это мое регулярное выражение (\\r|\\n|\\t)|(?:\D)(\:)

https://regex101.com/r/fV7wI2/1

enter image description here

Пожалуйста, обратите внимание, что я пытаюсь соответствовать : после субботы, но не : in Time for rmats например 12:00

Хотя изображение выше классифицирует захвата/Non группы Захват правильно

на управлении re.sub("(\\r|\\n|\\t)|(?:\D)(\:)",'',"Monday, Tuesday, Wednesday, Thursday, Friday, Saturday:")

возвращается

'Monday, Tuesday, Wednesday, Thursday, Friday, Saturda' (отсутствует 'у' после субботы)

вместо

'Monday, Tuesday, Wednesday, Thursday, Friday, Saturday'

Почему это так?

ответ

2

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

import re 
s = "Monday, Tuesday, Wednesday, Thursday, Friday, Saturday:" 
print(re.sub(r"[\r\n\t]|(?<!\d):",'',s)) 
#       ^^^^^^^ 
# Result: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday 

См IDEONE demo

Здесь (?<!\d) проверяет, не является ли предыдущий символ перед двоеточием.

Кроме того, чередование включает дополнительные накладные расходы, предпочтительный класс символов [\r\n\t], и вам не нужны никакие группы захвата (круглые скобки), так как вы их вообще не используете.

Также обратите внимание, что регулярное выражение инициализируется строковым литералом, чтобы избежать переопределения.

Некоторые more details from Python Regular Expression Syntax относительно без захвата групп и отрицательных просмотровых-задов:

(?<!...)
- спички, если текущая позиция в строке не предшествует матч за .... Это называется отрицательное утверждение lookbehind. Подобно позитивным утверждениям lookbehind, содержащийся шаблон должен соответствовать только строкам некоторой фиксированной длины и не должен содержать ссылки на группы. Шаблоны, начинающиеся с отрицательных утверждений lookbehind, могут совпадать в начале поиска строки.

(?:...)
- Неконвертируемая версия обычных скобок.Соответствует любому регулярному выражению внутри круглых скобок, но подстрока, сопоставляемая с группой, не может быть восстановлена ​​после выполнения соответствия или ссылки позже в шаблоне.

Как просмотровых задом являются нулевой шириной утверждения (= выражения возвращающегося истинного или ложных без перемещения индекса дальше в строке), они именно то, что вам нужно в этом случае, когда вам хочу проверить, но не матч. Не захватывающая группа будет потреблять часть строки и, таким образом, будет частью матча.

+0

Я думаю, вы неправильно поняли термин «не захватывающий». Это просто означает, что он не сделает отдельную захваченную группу для подтекста, сопоставленного с группой, но подтекст по-прежнему будет частью матча. Я обновил свой ответ и уточнил шаблон регулярного выражения. Пожалуйста, проверьте и дайте мне знать, если вам нужно больше разъяснений. Я думаю, [* Lookarounds Stand the Ground *] (http://www.rexegg.com/regex-lookarounds.html#stand_their_ground) является обязательным для вас. –

+0

clear & detail, thanks – wolfgang

1

\D не является цифрой. В saturdayy является non digit, поэтому он удаляется.

Использование

print re.sub("(\\r|\\n|\\t)|(?<=\D):",'',"Monday, Tuesday, Wednesday, Thursday, Friday, Saturday:") 

Использование lookahead обеспечит вам не удаленные дополнительные символы перед :/

+0

'y' is' non digit' Однако его не захватывающая группа '(?: \ D)', почему она будет сопоставлена? – wolfgang

+0

@wolfgang это не захватывает означает, что это не будет из 'group', и оно не будет храниться в' \ 1'. Захват или без его захвата iwll всегда будет сопоставлен – vks

+0

@wolfgang 'capture'' не является совпадением захвата регулярным выражением, но захватывает групп с помощью regex.it будет просто включать отключенные группы – vks

1

Я думаю, вы поняли, что (?:\D) не считая 1 письма в Regex, в действительности это не так, это просто не фиксирует \D в переменной $1. каждый раз, когда вы используете (...), вы должны понимать, что любой узор внутри (...) будет занесен в переменную либо $1, $2, ... в Regex.

Лучший способ справиться с этой проблемой - использовать положительный/отрицательный взгляд в качестве ответа от @vks и @stribizhev, потому что lookaround - это просто утверждение, которое не потребляет никакой буквы, поэтому мы называем их "нулевой шириной утверждение ".

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