2010-09-30 3 views
1

Я пишу программу на C#, которая сравнивает строки так же, как Google ищет документы по ключевым словам.Как я могу увидеть, если одна строка свободно содержит другую (случай, лишние пробелы и пунктуация игнорируются)?

Я хочу поискать «переполнение стека», чтобы вернуть true для «переполнения стека» (plain), «Это переполнение стека». (посередине), «Добро пожаловать в переполнение стека». (без учета регистра), «Мне нравится переполнение стека». (переменная пробел) и «Кто ставит тире в переполнении стека?», но не «stackoverflow» (без пробелов).

Я думал, что могу использовать регулярное выражение типа «stack ([-] |.) + Overflow», кажется, слишком сложно заменить каждое место в каждом ключевом слове набором символов для каждого нового ключевого слова. Поскольку «переполнение стека» - это не единственная строка, которую я ищу, я должен сделать это прагматично.

+0

Похоже, вам понадобятся алгоритмы с нечеткой логикой. Быстрый поиск вызывает расстояние Левенштейна как один из способов измерения количества изменений, необходимых для преобразования одной строки в другую. –

+0

Этот связанный вопрос предоставляет некоторые возможности: http://stackoverflow.com/questions/1358687/what-are-some-good-methods-to-find-the-relatedness-of-two-bodies-of-text –

ответ

1

Чтобы удовлетворить ваши спецификации, вы можете сначала сделать

newSearchString = Regex.Replace(Regex.Escape(searchString), @"\s+", @"[\s\p{P}]+"); 

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

Но, конечно, это не будет соответствовать малейшей опечатке, тогда как алгоритм, использующий расстояние Левенштейна, также будет соответствовать «Stak Overfloor».

1

Если вы просто хотите добиться эффекта в указанном конкретном случае, вы можете использовать регулярные выражения для замены токенов, которые вы хотите игнорировать, на одном пробеле (или пустой строке).

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

+0

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

+0

Я имел в виду конкретный случай «игнорировать случай, пробел и связь». Если вы хотите обрабатывать возможные совпадения в случае опечаток, то вы будете искать что-то более развитое, такое как динамическое программирование. Если вы сравниваете входную строку со всеми возможными совпадениями, она вернет стоимость соответствия для каждой строки, и вы можете выбрать ключевое слово с наименьшей стоимостью как «совпадение» с определенной степенью неопределенности (высокая стоимость соответствия -> маловероятное соответствие) , Ничто не мешает вам использовать гибридный подход: заменить регистр, пробел, пунктуацию, а затем использовать динамическое программирование. –

0

Если вы сравниваете против коротких строки, то самый простой способ, что я могу видеть бы вырезать все белое пространство и другие символы из обоих строк и сделать простой string.Contains.

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

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