2009-03-30 4 views
13

Мне нужно создать регулярное выражение, которое может соответствовать нескольким строкам. Например, я хочу найти все экземпляры «хорошо» или «отлично». Я нашел несколько примеров, но не кажется, что я пришел с работы:Regex для соответствия нескольким строкам

\b(good|great)\w*\b 

Может кто-нибудь мне точку в правильном направлении?

Редактировать: Я должен отметить, что я не хочу просто соответствовать целым словам. Например, я могу также совместить «ood» или «reat» (части слов).

Редактировать 2: Вот несколько примеров текста: «Это действительно замечательная история». Возможно, мне захочется сопоставить «это» или «действительно», или мне может потребоваться совпадение «eall» или «reat».

+1

Вы хотите совместить "oo", "o" или "t"? – jpalecek

+3

Как насчет ooooooooooooooooooooooooooooooooooooooooooooooooooo? –

+0

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

ответ

21

Если вы можете гарантировать, что нет зарезервированных регулярных выражений символов в списке слов (или, если вы их избежать), вы могли бы просто использовать этот код, чтобы сделать a big word list в @"(a|big|word|list)". Нет ничего плохого в операторе |, поскольку вы его используете, если те () окружают его. Это звучит как \w*, а шаблоны \b - это то, что мешает вашим матчам.

String[] pattern_list = whatever; 
String regex = String.Format("({0})", String.Join("|", pattern_list)); 
+1

Возможная ошибка: это должен быть String.Join ("|", word_list), а не String.Join (word_list, "|"), см. Также http://msdn.microsoft.com/en-us/library/57a79xd0 .aspx – David

+0

Хороший улов - спасибо! Я обновил свой ответ. – ojrac

+1

В отличие от вопроса, он не будет соответствовать, например, '" ood "' in '" good ". – MikeM

4
(good)*(great)* 

после редактирования:

\b(g*o*o*d*)*(g*r*e*a*t*)*\b 
+0

Не будет ли это соответствовать oooooooooooooooooooooooooooooooooooooooodddddddddddddddddddddddddddddd? –

+0

Да, наряду с «gore», «gogogo» и связью других непреднамеренных комбинаций. – Randy

0

Я не понимаю проблему правильно:

Если вы хотите, чтобы соответствовать «большой» или «Reat» вы можете выразить это по шаблону, как:

"g?reat" 

Это просто говорит, что «reat» -part должен существовать, а «g» является необязательным.

Это будет соответствовать «reat» и «great», но не «есть», потому что требуется первое «r» в «reat».

Если у вас есть тоже слова «большой» и «хорошо», и вы хотите, чтобы соответствовать их обоих с дополнительным «г» вы можете написать это так:

(g?reat|g?ood) 

И если вы хотите включить слово-граница, как:

\b(g?reat|g?ood) 

вы должны знать, что это не будет ничего подобного «Breat» совпадают, потому что у вас есть «ечить», но и «г» не на границе слова из-за «б ».

Так что, если вы хотите, чтобы соответствовать целым словам, которые содержат ссылку подстроки «Reat» или «ООД», то вы должны попробовать:

"\b\w*?(reat|ood)\w+\b" 

Это гласит: 1. Начиная с границей слов начинают соответствие любого число слов-символов, но не будьте готовы. 2. Совпадение «reat» или «ood» означает, что только те слова совпадают, которые содержат один из них. 3. Сопоставьте любое количество словных символов, следующих за «reat» или «ood», пока не будет достигнута следующая граница слова.

Это будет соответствовать:

«добро», «хорошо», «ООД» (если полное слово)

Это может быть прочитана как: Дайте мне все полные слова, которые содержат «ООД» или "Reat".

Это то, что вы ищете?

1

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

function wordPermutations($word, $minLength = 2) 
{ 
    $perms = array(); 

    for ($start = 0; $start < strlen($word); $start++) 
    { 
     for ($end = strlen($word); $end > $start; $end--) 
     { 
      $perm = substr($word, $start, ($end - $start)); 

      if (strlen($perm) >= $minLength) 
      { 
       $perms[] = $perm; 
      } 
     } 
    } 

    return $perms; 
} 

испытания Код:

$perms = wordPermutations('great', 3); // get all permutations of "great" that are 3 or more chars in length 
var_dump($perms); 

echo ('/\b('.implode('|', $perms).')\b/'); 

Пример вывода:

array 
    0 => string 'great' (length=5) 
    1 => string 'grea' (length=4) 
    2 => string 'gre' (length=3) 
    3 => string 'reat' (length=4) 
    4 => string 'rea' (length=3) 
    5 => string 'eat' (length=3) 

/\b(great|grea|gre|reat|rea|eat)\b/ 
1

Я думаю, что вы просят о том, что вы действительно не имеете в виду , если вы хотите найти любую часть t он слово, вы litterally ищет письма

например. Поиск {Джек, Джим} в "Джоне и Шелли прохладный"

ищет все буквы в названиях {J, а, с, к, я, м}

* J * Ohn * * й Shelly * а * повторно

и для этого вам не нужно REG-EX :)

на мой взгляд, Суффикс Дерево может помочь вам с этим

http://en.wikipedia.org/wiki/Suffix_tree#Functionality

наслаждаться.

1

Просто проверьте для boolean, что Regex.IsMatch() возвращается.

if (Regex.IsMatch(line, "condition") && Regex.IsMatch(line, "conditition2")) 

Линия будет иметь как регулярное выражение, так и правое.

+0

В этом списке может быть более двух слов, и этот подход не очень хорошо масштабируется. Кроме того, я думаю, вам нужно только сопоставить одно из слов, то есть ваш '&&' должен быть '||'. Сам ответ имел много проблем с форматированием, синтаксисом и орфографией, которые я попытался исправить. Просмотрите мои изменения. –

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