2013-10-26 3 views
1

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

Учитывая строку S, я хочу найти все неперекрывающиеся подстроки, которые содержат подпоследовательность Q, которая подчиняется определенным правилам. Предположим теперь, что я ищу подпоследовательность "abc". Я хочу, чтобы соответствовать подстроке S, который содержит 'a' с последующим в некоторой точке по 'b' с последующей в некоторой точке по 'c' с ограничением, что ни один 'a' не следует 'a', а не 'a' или 'b''b' не вытекает. Регулярное выражение, я использую это следующим образом (в Python):

regex = re.compile(r'a[^a]*?b[^ab]*?c') 
match = re.finditer(regex, string) 

for m in match: 
    print m.group(0) 

Для меня это ломается и звучит следующим образом:

a[^a]*?b: 'a' следовал наименьшую # символов не включая 'a' и заканчивающийся с 'b'
[^ab]*?c: самый маленький # символов не включая 'a' или 'b' и заканчивающийся с 'c'

Поэтому, ставя все это вместе, я предположил, что я буду сопоставлять неперекрывающиеся подстроки S, содержащие подпоследовательность «abc», которая подчиняется моим правилам исключения.

Этот работает отлично что-то вроде:

S = "aqwertybwertcaabcc", что дает мне "aqwertybwertc" и "abc",

но не удается работать S = "abbc", как он совпадает с "abbc".

+0

Значит, вы не хотите, чтобы он соответствовал '' abbc'''? Но это соответствует вашим требованиям. – jwodder

+0

Как я указал, что '' b'' не может следовать '' a'' или '' b''? –

+1

Вы сказали, что 'a' сопровождается * в какой-то точке * буквой' b', за которой не следуют другие 'b', а в' 'abbc'' второй' b' является 'b' после' a', за которым не следует другое 'b'. В ваших спецификациях никогда не запрещалось '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''. – jwodder

ответ

3

Предполагая, что вы на самом деле хотите, для подпоследовательности Q не содержит ни одного a сек между первым a и первым b и не a с или b с между первым b и первым c после первого b, правильное регулярное выражение для использования является:

r'a[^ab]*b[^abc]*c' 

регулярное выражение, что вы используете будет делать все, что он может добиться успеха на шнурке, в том числе соответствие буквального b к b после первого b, поэтому "abbc". Только путем исключения исключая b в классе первого символа, этого можно избежать, и b должен быть выполнен только для первого b после a.

+0

Я понимаю вашу логику, но я не понимаю, почему не-жадное соответствие '*?' В моем регулярном выражении не запретит 'b' следовать за' a'. Как и я, я думал, что это займет первый «b», следующий за «a», а затем следующий примет первый «c» при условии, что символы между ними не включали 'a' или' b'. –

+0

@SteveP .: Non-greedy просто означает, что он потребляет как можно меньше символов * при попытке успешно совместить *. Если для успешного сопоставления требуется потребление дополнительного символа или два, он будет потреблять дополнительный символ или два. – jwodder

+0

Хорошо, это имеет смысл. Большое спасибо! –

0

Это может помочь, если вы посмотрите на обратный класс.
Во всех случаях abc - это тривиальное решение.
И в этом случае не жадные, вероятно, не применяются, потому что
существуют фиксированные множества символов, используемые в примерах обратных классов.

# Type 1 : 
# (b or c can be between A,B) 
# (a or b can be between B,C) 
# ------------------------------ 
a     # 'a'    
[b-z]*?    # [^a] 
b     # 'b' 
[abd-z]*?   # [^c] 
c     # 'c' 


# Type 2, yours : 
# (b or c can be between A,B) 
# (c can be between B,C) 
# ------------------------------ 
a     # 'a'    
[b-z]*?    # [^a] 
b     # 'b' 
[c-z]*?    # [^ab] 
c     # 'c' 


# Type 3 : 
# (c can be between A,B) 
# ------------------------------ 
a     # 'a'    
[c-z]*?    # [^ab] 
b     # 'b' 
[d-z]*?    # [^abc] 
c     # 'c' 


# Type 4 : 
# (distinct A,B,C) : 
# ------------------------------ 
a     # 'a'    
[d-z]*?    # [^abc] 
b     # 'b' 
[d-z]*?    # [^abc] 
c     # 'c' 
Смежные вопросы