2012-06-20 2 views
2

У меня есть текст, в котором каждая строка текста содержит хорошие слова и некоторые плохие (нежелательные) слова. Таким образом, модель может выглядеть следующим образомМожет кто-то объяснить объяснение жадности в этом регулярном выражении

good1-good2 good3 bad1-good4-bad2 some more good words 
good1-good2 good3 bad1 bad2 
good1-good2 good3 bad1 bad2 bad3 

Теперь я должен отвергнуть все, что в строке ниже, а также в том числе первого плохого слова Так

good1-good2 good3 bad1-good4-bad2 some more good words должен стать good1-good2 good3

good1-good2 good3 bad1 bad2 должны стать good1-good2 good3

good1-good2 good3 bad1 bad2 bad3 должно быть good1-good2 good3

Я использую питона так это то, что я сделал

p=re.compile('([\w \d-]+) (bad1|bad2|bad3).+',re.I) 
m=p.search('good1-good2 good3 bad1-good4-bad2 ') 
m.group(1) 

и это дает good1-good2 good3 , который является то, что я хочу, но

m=p.search('good1-good2 good3 bad1 bad2 ') 
m.group(1) 

возвращает good1-good2 good3 bad1 Я подумал, что, поскольку + жаден так + в ([\w \d-]+) идет по совпадающим символам до конца строки, а затем возвращается назад, чтобы найти последнее плохое слово, которое в этом случае равно bad2, но когда я делаю это

p=re.compile('([\w \d-]+) (bad1|bad2|bad3).+',re.I) 
m=p.search('good1-good2 good3 bad1 bad2 bad3') 
m.group(1) 

оно снова возвращает good1-good2 good3 bad1. Не могли бы вы объяснить это? Потому что может возникнуть проблема с моим пониманием greediness в regex? Хотя я решил решить эту проблему с помощью регулярного выражения ([\w \d-]+?) (bad1|bad2|bad3).+, но все же я не понимаю, почему использование ([\w \d-]+) (bad1|bad2|bad3).+ всегда возвращает первое плохое слово (bad1 в этом случае)?

Спасибо за внимание.

Edit: Но предположим, что у меня есть шаблон только с хорошими словами и без плохих слов, как good1-good2 good3--only good words то, что должно быть регулярное выражение? Я пробовал это регулярное выражение ([\w \d-]+?) ?(bad1|bad2|bad3)?.*, но это возвращает первую букву шаблона.

+0

Первый суб-модель также жадный, поэтому он получает большую часть его может совпадать, затем второй и т. д. – poncha

+0

@poncha моя проблема - это третий случай. почему он возвращает 'good1-good2 good3 bad1', когда я смотрю в' good1-good2 хорошо3 плохой1 плохой2 плохо3'? Он должен был возвратить 'good1-good2 good3 bad1 bad2' в соответствии с моим пониманием жадного – lovesh

ответ

3

Что касается этого случая:

m=p.search('good1-good2 good3 bad1 bad2 ') 

Вы правильно. ([\w \d-]+) жадный, поэтому он «ест» как можно больше и отступает.

Что касается этого случая, однако:

m=p.search('good1-good2 good3 bad1 bad2 bad3') 

Что вы, вероятно, не видите, что ваш .+ должен соответствовать по крайней мере один символ после плохого слова. Вот почему регулярное выражение не может совпадать с bad3 как плохим словом: если бы это произошло, у него закончилось бы количество символов для .+, чтобы соответствовать чему-либо. Таким образом, он снова возвращается к bad2. Измените свой .+ на .*, чтобы увидеть разницу.Это связано только с тем, что в первом случае у вас было дополнительное пространство, i.e.bad2, что вещи «отработаны, как ожидалось».

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

EDIT

Для редактируемой части вопроса, как написано на @lovesh из приведенных ниже комментариев:

([\w \d-]+?) ?(bad1|bad2|bad3|$) 
+0

Большое спасибо за помощь. – lovesh

+0

Я знаю, что принял ваш ответ, но я понял, что пропустил что-то. Я отредактировал мой вопрос. Не могли бы вы помочь? Спасибо – lovesh

+0

В вашем редактировании он возвращает только первую букву, потому что вы сделали первую часть неживой, т. Е. '' ([\ W \ d -] +?) '', Поэтому ей нужно было бы только совместить одну букву, в то время как ''. * '' берет все остальное. Я думал о решении, но на самом деле это сложная проблема ... Я вернусь к вам. –

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

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