2014-12-19 3 views
-2

Предположим, у меня есть список ключевых слов около 30-40, и я бы хотел найти все или любые из этих слов в очень длинном тексте, давайте немножко тысячи слов. Только идея у меня есть - используйте несколько регулярных выражений и добавьте совпадения к List<string>. Есть ли лучшее решение?Поиск большого количества слов в длинной строке

P.S. Эти ключевые слова могут быть разделены комой, а также один за другим по тексту.
P.P.S. Например, это текст из Википедии.

Мне нужно найти слова: «Шекспир», «Английский», «Язык».

Уильям Шекспир (/ ʃeɪkspɪər/[1] 26 апреля 1564 (крещен) - 23 апреля 1616) [пь 1] был английский поэт, драматург и актер, получивший широкое признание как величайший писатель в Английский язык и выдающийся драматург мира [2]. Его часто называют национальным поэтом Англии и «Бардом Эйвона». [3] [nb 2] Его сохранившиеся произведения, в том числе некоторые из них, состоят из 38 пьес, [nb 3] 154 сонетов, двух длинных повествовательных стихотворений и несколько других стихов, авторство некоторых из которых является неопределенным. Его пьесы были переведены на каждый большой живой язык и исполняются чаще, чем у любого другого драматурга. [4] Шекспир родился и вырос в Стратфорде-на-Эйвоне. В возрасте 18 лет он женился на Анне Хэтэуэй, с которой у него было трое детей: Сюзанна и близнецы Хамнет и Джудит. В период с 1585 по 1592 год он начал успешную карьеру в Лондоне в качестве актера, писателя и частичного владельца игровой компании под названием «Люди Лорда Чемберлена», позже известной как «Царские мужчины». Он, кажется, ушел в Стратфорд около 1613 года в возрасте 49 лет, где он умер три года спустя. Немногие записи о частной жизни Шекспира выживают, и были значительные размышления о таких вещах, как его физическая внешность, сексуальность, религиозные убеждения и о том, написаны ли произведения, приписываемые ему, другими. [5] Шекспир произвел большую часть своей известной работы между 1589 и 1613 годами. [6] [nb 4] Его ранние пьесы были в основном комедиями и историями, и эти работы по-прежнему считаются одной из лучших работ, созданных в этих жанрах. Затем он написал в основном трагедии примерно до 1608 года, в том числе Гамлет, Король Лир, Отелло и Макбет, которые считались одними из лучших произведений на английском языке. На последнем этапе он написал трагикомиды, также известные как романсы, и сотрудничал с другими драматургами.

+0

пример будет лучше. –

+1

Что вы хотите, чтобы ваш результат выглядел? слова с индексами, где они были найдены? Или просто да/нет? – Jonesopolis

+0

Я отредактировал ваш заголовок. Пожалуйста, смотрите: «Если вопросы включают« теги »в их названиях?] (Http://meta.stackexchange.com/questions/19190/), где консенсус« нет, они не должны ». –

ответ

4

Если вы хотите получить список ключевых слов, которые содержатся в строке, то, как это будет работать:

var results = myKeywordList.Where(k => myBigLongString.Contains(k)); 

Вы можете также использовать Any, для булева результата, или Count для числа вместо от Where

Это fiddle отображение результатов.

Если вы хотите сделать это без учета регистра использования ToLower на длинной строке и k

+0

Насколько я понимаю, k - это массив ключевых слов? Как добавить все соответствующие слова в список ? –

+0

k - каждое ключевое слово в списке. Поэтому он будет искать вашу строку для каждого ключевого слова. – paqogomez

+0

@ andrey.shedko 'results' будет всеми ключевыми словами, которые существуют в вашем тексте. – paqogomez

1

Вы можете использовать положительное и отрицательное lookaround утверждение, как показано ниже.

@"(?<!\S)(?:Shakespeare|English|Language)(?!\S)" 

Добавить (?i) модификатор, чтобы сделать регистр, нечувствительный к регистру.

@"(?i)(?<!\S)(?:Shakespeare|English|Language)(?!\S)" 

DEMO

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

@"(?i)(?<=^|[,\s])(?:Shakespeare|English|Language)(?=[,\s]|$)" 
+1

Спасибо. Вероятно, это тоже поможет, но я предпочитаю LINQ. –

1

Вы ищете IndexOf

MSDN

Perls Example

int pos = mytext.IndexOf("Shakespear"); 

if(pos >= 0){ /*Shakespear found*/ } else {/*Shakespear not found*/} 

Использование IndexOf даст вам стартовую позицию, которая позволит вам использовать метод Substring для извлекать строку и манипулировать ими, но вам нужно.

1

Вы можете построить подвыражение с помощью списка экранированных слов.
как

(псевдо-код)
string rx_list = "(" + RregEscape(MyArray.join("|")) + ")";

Затем Dot-Net может сделать выражение да/нет условными.
Используя эту информацию, вы можете обернуть подвыражение «rx_list» в
выражение арбитража границы.

string regex_final = @"(?(?=\w)\b|\B)" + rx_list + @"(?(?<=\w)\b|\B)";

Пример результата регулярное выражение Строка:

# (?(?=\w)\b|\B)(Shakespeare|English|Language)(?(?<=\w)\b|\B) 

(?(?= \w)   # Conditional, is next letter a word 
     \b     # yes, word boundry 
    | \B     # no, not word boundry 
) 
(     # (1 start) 
     Shakespeare 
    | English 
    | Language 
)     # (1 end) 
(?(?<= \w)   # Conditional, was prev letter a word 
     \b     # yes, word boundry 
    | \B     # no, not word boundry 
) 
+0

Спасибо за такой расширенный ответ. –

+0

@ andrey.shedko - Нет проблем. На сегодняшний день это самый быстрый способ сделать это. – sln

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