Loading...
DHristoskov avatar DHristoskov 211 Точки

[Homework]C# Advanced - Regular Expression- Problem {4} Sentence Extractor.

Здравейте колеги, започнах да решавам домашното за Regular Expression, и установих че всъщност аз май нищо не знам. Ще ми нужно доста повече от един месец за да започна да се справям с Regex.Цяла сутрин се боря със задача 4: Sentence Extractor.Написах много различни решения и винаги зациклям на едно и също място. Подадената дума в условието е „is“ и коректния отговора трябва да е (This is my cat!; And this is my dog.), но при мен като отговор отпечатва също We happily live in Paris – the most beautiful city in the world!,защото в „Paris има „is“.Предполагам трябва да направя pattern (@”\bis\b” или в моя случай @“\\b”+word+”\\b”), за да търси само конкретната самостоятелна дума, но не ми се получава.Ще се радвам на малко помощ.

Това е решението ми 4: Sentence Extractor, но без втори Regex за търсената дума.

Благодаря!

П.С. Предполагам задачата е лесна, но на мен нищо не ми идва на ум. Може би гледам в грешната посока.

Тагове:
1
C# Advanced 12/05/2015 12:22:43
enevlogiev avatar enevlogiev 1168 Точки

Здравей, не съм запознат с регексите в C#, но в PHP eй този регекс :

([A-Z][\w\W]*?\bis\b[\w\W]*?[.!?])

ще хваща изреченията с дума 'is' в тях. Ако принципът е същият, би трябвало да ти свърши работа.

Edit:
Сега да обясня.

[A-Z] - търси една голяма буква.

[\w\W] - хваща ВСИЧКО. В случая [A-Z][\w\W]* ще хване всичко от първата голяма буква до края. Но :

[\w\W]*? e lazy matcher - т.е. ще спре при първото \sis\s.

\sis\s - търси думата 'is' с два whitespace oт двете й страни. ' is ' няма да работи коректно, защото ' ' не е равно на newline, примерно.

Второ [\w\W]*? - ще хване всичко от \sis\s до първата '.' , '?', '!', която открие.

[.!?] казвам, че изречението трябва да завърши с един от трите charactera.

В случая може да мине и без външните кръгли скоби, сложих ги, защото така ми е по-прегледно в един сайт, който ще препоръчам - regex101.com

 

Втора редакция:

правилно е \bis\b , вместо \sis\s. Не бях съобразил, че изречение може да завърши с думата 'is', примерно That's how it is!

8
12/05/2015 12:54:15
DHristoskov avatar DHristoskov 211 Точки

Благодаря ти много, така стана.

0
enevlogiev avatar enevlogiev 1168 Точки

За нищо, обърни внимание, че внесох лека корекция в регекса.

2
a_rusenov avatar a_rusenov 1103 Точки

Или така:

\s*(.*?\bis\b.*?[.!])

Слагаш word boundary (\b) около думата, като около нея може да има всичко (.*?) 0 или няколко пъти. Ползва се .* заедно с lazy оператора ?, за да се хване всичко до първия срещнат препинателен знак (иначе ще хване всичко до последния срещнат). 

Накрая хващяш цялото изречение в група () и преди нея казваш че може да има нула или повече интервала (\s*), като този път е без ?, защото искаш да ги хване всичките.

1
12/05/2015 12:53:05
DHristoskov avatar DHristoskov 211 Точки

Може би грешката ми беше че аз първо отделих изреченията които завършват на ". ? !", и след това се опитвах да сортирам втори път за дадената дума.

0
DHristoskov avatar DHristoskov 211 Точки

Така се получава но фиксирам търсената дума в изречението:

 Regex line = new Regex(@"[A-Z][\w\W]*?\sis\s[\w\W]*?[.!?]");
 MatchCollection matches = line.Matches(text);
 var list = matches.Cast<Match>().Select(x => x.Value).ToList();     
 list.ForEach(b => Console.WriteLine(b));

1
enevlogiev avatar enevlogiev 1168 Точки

Просто конкатенирай -

"left part" + търсена дума + "right part"

2
DHristoskov avatar DHristoskov 211 Точки

Аз успях да я направя и сега работи както трябва, проблема ми беше че аз в началото отделих изреченията, които завършват на ". ! ?"(както е по условие) и след това се опитвах да ги сортирам втори път по това дали подадената дума е част от тях.И всичко това защото този Regex е доста сбъркан и не ми е много ясен, ако знаех как да си направя pattern-а щях да го направя с едно сортиране, както го направих с твоя помощ.

0
tutzy.fts avatar tutzy.fts 2 Точки

Това с конкатенирането е точно в десятката. Не се бях сетила.

0
Inspix avatar Inspix 51 Точки

Здравей, аз току що реших задачата с следния Regex

(\w[^.!?]*)?\bis\b[^.!?]*[.!?]

 

Ще споделя как аз ги разбирам нещата, моля някой да ме поправи, ако някъде бъркам.

(\w[^.!?]*) Капчъринг група която мачва изречение започващо с word чаръктър(\w([A-Z] е по-коректно защото изреченията почват с главна буква, но по-условие го няма) последвано от максимален брой знаци, които не са ".","!","?" (защо не мачвам всички знаци? [\w\W] ще мачне "Hello. What's up dog?" Докато [^.!?] спира матча при един от тези знаци - "Hello." и " What's up dog!"

В случай, че is е в началото на изречението искаме горната група да се пропусне.

\bis\b Тук търсим дадената дума, като използваме баундри за да избегнем проблема с думата в кавички, скоби и тн. Ако искаме да матчнем само тази дума case-insensitive може да направим така (?i:\bis\b)

[^.!?]* последвана от максимален брой знаци, които не са".","!","?"

[.!?] като матча завършва на ".","!","?"

 

Ето и решението: Sequence Extractor

 

Поздрави!

5
Filkolev avatar Filkolev 4482 Точки

По принцип ползването на регулярни изрази в такъв тип задачи, където условието е малко лаконично, не е особено лесно. За да напишеш един качествен регекс трябва да знаеш отлично какво искаш да хванеш и какво не. Доста е лесно иначе да напишеш нещо, което да проработи с дадените примери и след това някой да го счупи.

Ето какво според мен би сработило в достатъчно добра степен, без да е идеално решение: \b.*?\bis\b.*?[!.?]

Какво казвам с този израз:

  • Трябва да има граница на дума в началото. Не е fool-proof, но да кажа, че искам главна буква също не е ако имам такава по средата на изречение.
  • .*? - хваща всичко, но възможно най-малко, lazy. Т.е. спира да хваща, ако стигне до следващото, което съм указал да се хване, в случая думата, която търсим.
  • is е оградено с \b, за да не го мачваме ако е вътре в друга дума.
  • Отново .*?, за да хвана остатъка от изречението
  • Накрая просто казвам, че искам да завърша с точка, удивителна или въпросителна.

Без да е дадена повече информация, бих счел доста варианти на решения за верни, т.е. ако работи с примерите, спокойно може да кажем, че е достатъчно добро решение, дори да не работи във всички случаи.

1
enevlogiev avatar enevlogiev 1168 Точки

Koлегата Inspix е прав, добре е да се ползва [^.!?] вместо .*? , или [\w\W].

Причината - тествай върху This bla bla. This is my dog., примерно. А ако кажеш, че в началото искаш главна буква, по никакъв начин не ти влияе на главните букви в средата на изречението. Последен вариант (или предпоследен):
\b[A-Z][^!.?]*?\bis\b[^!.?]*?[.!?]

2
Filkolev avatar Filkolev 4482 Точки

Първото .*? е по-добре да е [^.?!]+, прав си.

Така изразът става: \b[^.?!]+\bis\b.*?[!.?]

1
DHristoskov avatar DHristoskov 211 Точки

Благодаря на всички за помощта, но както изглежда аз ще трябва да отделя допълнително време на тези изрази, защото все още много неща изобщо не са ми ясни.

0
ZlatinDimitrov avatar ZlatinDimitrov 11 Точки

Здрасти DHristiskov!Не си сам!:)И аз ударих греда с тази тема!Все едно се мъча да си говоря с японец на български:Изгледах много видеа и аз стигнах горе-долу до някакво решение.

0
16/05/2015 22:55:25
NikolayUzunov avatar NikolayUzunov 7 Точки

Видеа, stackoverflow, msdn, но на мен най-много ми помогна regex101 . Пишеш, тестваш и виждаш в дясно обяснения и какво match-ва . Даже смятам да си поблъскам главата чрез регулярни изрази да реша и други задачи от домашните .

0
iliqnvidenov avatar iliqnvidenov 16 Точки

Здравейте, на задача 4 не се иска да търсим изречение, в което има "is" ,а трябва да прочетем стринг от конзолата с търсения стринг, т.е "is" не е константа. Това съм направил аз и работи :

 string pattern = @"[\w ]+\b" +wordNeeded+ @"\b[\w ]+[!.?]";

Като тук wordNeeded  ми е стринга, който чета от конзолата.

0
Sadula avatar Sadula 1 Точки

Здравей :)

Да това което си написал е така но мачваш само тия изречения които завършват на .!? и ако вместо "is" се подаде "in" ще изкара the most beautiful city in the world! само вместо We happily live in Paris – the most beautiful city in the world! защото We happily live in Paris не завършва на .!?.
По-добрия вариант е @"\b[^.?!]+\b" + wordNeeded + "\b.*?[!.?]"

0
FireHead avatar FireHead 44 Точки

Ето го и моето решение. Доста е кратко и според мен даже красиво... ;)

Цък

0
16/05/2017 22:07:41
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.