2

Я пытаюсь найти полное предложение, содержащее поисковый запрос. я пробовал

grep (^.|\.\s).*searchterm.*(\.\s|\n)

но это не работает, и я не уверен, почему.

Чтобы уточнить: я хочу, чтобы стандартный вывод напечатать полное предложение поискового запроса. Я использую grep для поиска по одному текстовому файлу.

Как пример, если мой файл имеет

" Foo blah. Blah blah searchterm blah blah. Foo bar."

Я хочу, чтобы стандартный вывод напечатать Blah blah searchterm blah blah

2 ответа2

2

Попробовал это на моем sh совместимом терминале:

$ grep --only-matching --perl-regexp "[^.]*searchterm[^.]*" \
       <<< "Foo blah. Blah blah searchterm blah blah. Foo bar."
Blah blah searchterm blah blah
$ 

Может быть сокращено до grep -oP .

Я думаю, что проблема с предоставленным вами регулярным выражением - это указание .* на то, насколько жадным вы хотите, чтобы он был (как заявил bertieb). Я просто переформулировал ваш запрос с «все, что заканчивается точкой» на «все, что не является точкой»

0

Это интересный вопрос, так как на первый взгляд он кажется относительно простым: «О, просто добавьте -P, чтобы получить разбор PCRE ... нет, подождите. Добавьте немного взгляда вперед и назад ... Негативный взгляд вперед и назад ... Замени эти жадные спички ... Почему я превышаю предел возврата PCRE? Хм ... "Внезапно это намного позже, и мой горшок чая почти исчез.

Решения:

Предположим, что во входных данных нет сокращений или других посторонних периодов. Используйте sed заменить периоды символами новой строки. Простой grep для searchterm:

$ sed 's/\./\n/g' input.txt | grep searchterm

Не предполагайте ничего, кроме установки perl (и новых строк при вводе). Используйте Lingua::EN::Sentence для извлечения предложений, имея дело с сокращениями и тому подобным.

$ perl -MLingua::EN::Sentence=get_sentences -ne 'print "$_\n" for grep { /searchterm/ } @{get_sentences($_)}' <(tr '\n' ' ' < input.txt)

(большое спасибо Tom Fenech в этом ответе на SO)

Еще одно потенциальное преимущество этого подхода помимо сопоставления, когда существуют посторонние периоды, заключается в том, что он также включает в себя окончательную остановку. Это не указано в вашем исходном вопросе, но в зависимости от того, что вы используете, он может сохранить добавление.

Обратите внимание, что для этого вам может потребоваться установить Lingua::EN::Sentence ; если у вас есть Perl, вы вполне можете иметь cpan и можете (sudo) cpan install Lingua::EN::Sentence .

Оба из них имеют предположения и используют инструменты, отличные от простого grep; и в основном не изменяйте свое регулярное выражение. Но они выполняют свою работу, как описано, по крайней мере, в моем тестировании на тексте lorem ipsum.

Редактировать: ответ Фелипе Лемы гораздо более простой, и я не уверен, как я пропустил его в тестировании. Я оставляю эти решения здесь для другого интереса; особенно второй для тех, кто ищет более сложный ввод.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .