2016-05-21 3 views
1

Мне нужно извлечь предложения, содержащие слово island или Island из абзаца. Каждое предложение начинается с заглавной буквы и заканчивается периодом.Получить предложения, содержащие ключевое слово из абзаца

Пункт в строке

" The islands were settled from the second century AD by a series of local empires. In 1819, Sir Stamford Raffles founded modern Singapore as a trading post of the East India Company; after the company collapsed, the islands were ceded to Britain and became part of its Straits Settlements in 1826. During World War II, Singapore was occupied by Japan. It gained independence from Britain in 1963, by uniting with other former British territories to form Malaysia, but was expelled two years later over ideological differences. After early years of turbulence, and despite lacking natural resources and a hinterland, the nation developed rapidly as an Asian Tiger economy, based on external trade and its human capital. " (Источник: https://en.wikipedia.org/wiki/Singapore)

Идеальный результат в качестве элементов массива:

  • острова поселили со второго века нашей эры серии локальных империй.
  • В 1819 году сэр Стэмфорд Раффлс основал современный Сингапур как торговый пост Ост-Индской компании; после того, как компания развалилась, острова были переданы в Великобританию и стал частью ее Straits поселений в 1826

Я нашел примеры о том, как сделать это на других языках, как Java (Regex to find sentence containing specific word (java) from paragraph). Однако одно и то же Regex не работало для Ruby.

Можно ли это использовать с помощью Ruby?

ответ

2

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

str.split(/(?<=\.)\s+/).select { |s| s =~ /\b[iI]slands?\b/ } 
    #=> ["The islands were settled from the second century AD by a series of local empires.", 
    # "In 1819, Sir Stamford Raffles founded modern Singapore as a trading post of 
    #  the East India Company; after the company collapsed, the islands were ceded to 
    #  Britain and became part of its Straits Settlements in 1826. * 
  • /(?<=\.)\s+/ совпадает с периодом в положительном просмотра назад с последующим одним или несколькими пробелами.
  • /\b[iI]slands?\b/ соответствует строкам «остров», «остров», «острова» и «острова», окруженные сломанными перерывами (во избежание совпадения, например, «островитянина»).

* Я добавил здесь два разрыва строки, чтобы сделать его более читаемым.

2

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

input.split('.').select do |sentence| 
    sentence.downcase.include?('island') 
end 

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

+0

Это удалит период после предложений. – sawa

+0

true :-) Должно быть легко добавить их обратно, хотя. –

+0

Что делать, если предложение содержит слово «островитянин»? Я бы, наверное, без Руби. Ruby трудно прочитать и понять, когда вы вернетесь к коду позже. Нет? Нет, если вы приобрели определенную компетенцию с языком, что верно для любого языка, включая регулярные выражения. –

0

Это решение дает правильный результат для текста примера.

text = " The islands were settled from the second century AD by a series of local empires. In 1819, Sir Stamford Raffles founded modern Singapore as a trading post of the East India Company; after the company collapsed, the islands were ceded to Britain and became part of its Straits Settlements in 1826. During World War II, Singapore was occupied by Japan. It gained independence from Britain in 1963, by uniting with other former British territories to form Malaysia, but was expelled two years later over ideological differences. After early years of turbulence, and despite lacking natural resources and a hinterland, the nation developed rapidly as an Asian Tiger economy, based on external trade and its human capital." 

matches = text.scan(/\b[A-Z][^.]+[Ii]sland[^.]+?\./) 

matches.each do |match| 
    puts "Found: #{match}" 
end 

Это производит следующий вывод:

Found: The islands were settled from the second century AD by a series of local empires. 
Found: In 1819, Sir Stamford Raffles founded modern Singapore as a trading post of the East India Company; after the company collapsed, the islands were ceded to Britain and became part of its Straits Settlements in 1826. 

На основании указанной ссылки, дополнительная поддержка для других предложений терминатора («!» «?», Например, и) может быть добавлен просто с этим небольшим изменением :

matches = text.scan(/\b[A-Z][^.!?]+[Ii]sland[^.!?]+?[.!?]/) 
0

Вы можете использовать это регулярное выражение

(?<=^|[.?!])(.*?[Ii]sland.*?(?:[.?!]|$)) 

Rubular Demo

рубин Код

print str.scan(/(?<=^|[.?!])(.*?[Ii]sland.*?(?:[.?!]|$))/) 

Ideone Demo

1

Да.После того, что вы сказали, самый простой, пожалуй:

string.scan(/(?=[A-Z])[^.]*island[^.]*\./i) 
# => [ 
# "The islands were settled from the second century AD by a series of local empires.", 
# "In 1819, Sir Stamford Raffles founded modern Singapore as a trading post of the East India Company; after the company collapsed, the islands were ceded to Britain and became part of its Straits Settlements in 1826." 
# ] 
Смежные вопросы