Что относительно того, чтобы хранить freetext столбец, который показывает удобную для пользователя версию номера телефона, затем нормализованная версия, которая удаляет пробелы, скобки и расширяется '+'. Например:
Удобный для пользователя: +44 (0) 181 4642542
Нормализованный: 00441814642542
Как вы заметили, токенизация предложений немного сложнее, чем может показаться на первый взгляд. Так что вы также можете воспользоваться преимуществами существующих решений. Алгоритм токенизации предложений Punkt популярен в NLP, и есть хорошая реализация в Python Natural Language Toolkit , использование которого описывается здесь . Они также описывают другой подход здесь .
Возможно, существуют другие реализации, или вы также можете прочитать исходную статью , описывающую алгоритм Пункта: Kiss, Tibor and Strunk, Jan (2006) ): Неконтролируемое определение границ многоязычного предложения. Computational Linguistics 32: 485-525.
Вы также можете прочитать еще один вопрос Stack Overflow о токенизации предложений здесь .
your_string = "First sentence. Second sentence. Third sentence"
sentences = your_string.split(".")
=> ["First sentence", " Second sentence", " Third sentence"]
Нет необходимости усложнять простой код.
Изменить : Теперь, когда вы пояснили, что реальный ввод более сложен, чем ваш первоначальный пример, вы должны проигнорировать этот ответ, поскольку он не рассматривает крайние случаи. Однако первый взгляд на НЛП должен показать вам, во что вы ввязываетесь.
Некоторые из крайних случаев, которые я видел в прошлом, были немного сложными:
Если вы планируете анализировать эти тексты, вам не следует использовать расщепления или регулярные выражения.
irb(main):005:0> a = "The first sentence. The second sentence. And the third"
irb(main):006:0> a.split(".")[0...2]
=> ["The first sentence", " The second sentence"]
irb(main):007:0>
РЕДАКТИРОВАТЬ: вот как вы обрабатываете случай «Это предложение ...... и другое. И еще одно ...»:
irb(main):001:0> a = "This is the first sentence ....... And the second. Let's not forget the third"
=> "This is the first sentence ....... And the second. Let's not forget the thir
d"
irb(main):002:0> a.split(/\.+/)
=> ["This is the first sentence ", " And the second", " Let's not forget the thi rd"]
И вы можете применить тот же диапазон оператор ...
для извлечения первых 2.
Обычно это соответствует предложениям.
/\S(?:(?![.?!]+\s).)*[.?!]+(?=\s|$)/m
В вашем примере с двумя предложениями возьмите первые два совпадения.
You will find tips and software links on the sentence boundary detection Wikipedia page.
Если вы знаете, какие предложения искать, Regex должен хорошо выполнять поиск
((YOUR SENTENCE HERE)|(YOUR OTHER SENTENCE)){1}
Split, вероятно, займет довольно много памяти, так как он также сохраняет вещи, которые вам не нужны ( весь текст, который не является вашим предложением), поскольку Regex сохраняет только искомое предложение (если, конечно, оно его находит)
If you're segmenting a piece of text into sentences, then what you want to do is begin by determining which punction marks can separate sentences. In general, this is !
, ?
and .
(but if all you care about is a .
for the texts your processing, then just go with that).
Now since these can appear inside quotations, or as parts of abbreviations, what you want to do is find each occurrence of these punctuation marks and run some sort of machine learning classifier to determine whether that occurance starts a new sentence, or whether it does something else. This involves training data and a properly-constructed classifier. And it won't be 100% accurate, because there's probably no way to be 100% accurate.
I suggest looking in the literature for sentence segmentation techniques, and have a look at the various natural language processing toolkits that are out there. I haven't really found one for Ruby yet, but I happen to like OpenNLP (which is in Java).