2014-11-14 3 views
-6

Я ищу решение в C# для поиска формата строки, введенного пользователем, перед вызовом SQL запросC# Полнотекстового поиск форматной строки: строка удалить все соседние дубликаты и добавить с «И» «ИЛИ»

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

select [title] from publications where contains([title], @searchString) 

основные вопросы:

1) add 'OR' by default between two words (ex C and C-1 below) 
1) remove adjacent duplicate from search string<br>(ex a,b,b-1, e below) 
2) remove 'AND' 'OR' at the end of the string (ex d below) 

Примеры:
вход => выход

a) "oyster and oyster or fish and clean water" => "oyster or fish and clean OR water"<br> 
b) "oyster and and fish and clean water" => "oyster and fish and clean OR water"<br> 
b-1) "oyster oyster fish fish clean and water"=> "oyster or fish or clean and water" 
c) "oyster fish" => "oyster or fish"<br> 
c-1) "oyster fish clean water" => "oyster or fish or clean or water" 
d) "oyster and" => "oyster"<br> 
e) "oyster and oyster" => "oyster"<br> 

текущий код (WCH потерпел неудачу в случае а, б и б-1; работает с-1, д, е)

string Format(string str) 
    { 
     List<string> searchKeywords = new List<string> { "and", "or" }; 
     //convert to lower case 
     str = str.Replace(",", " ").ToLower(); 

     Regex regex = new Regex(@"[ ]{2,}", RegexOptions.None); 
     //remove extra whitespace with space 
     str = regex.Replace(str, @" "); 

     //split string 
     string[] strArray = str.Split(' '); 

     List<string> outputArray = new List<string>(); 
     string output = ""; 
     string prevStr = ""; 
     string currStr = ""; 
     bool keywordFlag = false; 
     bool duplicateFlag = false; 

     //remove adjacent keyword or same words 
     foreach (var item in strArray) 
     { 
      currStr = item.Trim(); 
      keywordFlag = searchKeywords.Contains(prevStr) && searchKeywords.Contains(currStr); 
      duplicateFlag = outputArray.Contains(currStr) && !searchKeywords.Contains(currStr); 
      if (!currStr.Equals(prevStr) && !keywordFlag && !duplicateFlag) 
      { 
       outputArray.Add(currStr); 
       prevStr = currStr; 
      } 
     } 

     if (outputArray.Count() == 2 && searchKeywords.Contains(outputArray[1])) 
     { 
      outputArray.Remove(outputArray[1]); 
     } 

     output = string.Join(" ", outputArray); 
     if (output.Contains(" ") && !output.Contains("and") && !output.Contains("or")) 
     { 
      return string.Join(" or ", output.Split(' ').Select(I => I.Trim())); 
     } 
     return output; 
    } 


! [Выходной ток] [1]

устрицы и рыбы и чистая вода
устриц и рыбы и чистая вода
устрица рыба чистые и вод
устрица или рыба или чистые или вода
устрица или рыба
устрица
устрица

+3

Что вы пробовали, и какие у вас проблемы с вашими попытками? Просто размещение списка требований не является подходящим вопросом. – Servy

+0

Это всего лишь описание программы, а не вопрос. Мы не можем быть уверены в том, с чем вы столкнулись, если не показываете, что вы пробовали до сих пор, уточните, что конкретно является проблемой, и что вы хотите ответить. Без этого, это звучит так, как будто вы просите нас сделать это за вас. – tnw

+0

извините, это первый пост в stackoverflow, отправил мой код и вывел. – BeingDev

ответ

-1

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

В этом случае используйте String.Split(' ') для разделите searchstring на каждое пространство.

Используйте foreach петлю на результирующем массиве строк и использовать конкатенацию, чтобы закончить, если слово уже использовалось до этого не or или and, не добавляйте его в результирующую строку. Если предыдущее слово было or или and, а также текущий, не добавляйте его в результирующую строку. Если предыдущее слово не было or или and, а текущий нет, добавьте or к полученной строке.

EDIT: Теперь, когда код был опубликован, я могу видеть, что случилось

это условное:

if (output.Contains(" ") && !output.Contains("and") && !output.Contains("or")) 
    { 
     return string.Join(" or ", output.Split(' ').Select(I => I.Trim())); 
    } 

становится вызывается только, если выход не содержит экземпляр and или or

Выполните проверку, чтобы увидеть, если or необходимо добавить в вашей foreach петли, и избавиться от этого условного

e.г:

  foreach (var item in strArray) 
      { 
       currStr = item.Trim(); 
       keywordFlag = searchKeywords.Contains(prevStr) && searchKeywords.Contains(currStr); 
       duplicateFlag = outputArray.Contains(currStr) && !searchKeywords.Contains(currStr); 
       if (!currStr.Equals(prevStr) && !keywordFlag && !duplicateFlag) 
       { 
        if (!searchKeywords.Contains(prevStr) && !searchKeywords.Contains(currStr) && prevStr != "") 
        { 
         outputArray.Add("or"); 
        } 
        outputArray.Add(currStr); 
        prevStr = currStr; 
       } 
      } 

Кроме того, где вы проверяете, чтобы увидеть, если есть только 2 лексемы в массиве, вы учет только если они поставят or или and после слова, что произойдет, если они положили в or Oyster в качестве входной строки? Результирующая строка будет просто or

вы должны учитывать, что:

  if (outputArray.Count() == 2) 
      { 
       if(searchKeywords.Contains(outputArray[0])) 
        outputArray.Remove(outputArray[0]); 
       else if(searchKeywords.Contains(outputArray[1])) 
        outputArray.Remove(outputArray[1]); 
      } 
+0

отправил код – BeingDev

+0

спасибо за предложение, это помогает.
для подсчета = 2
, если (outputArray.Count() == 2) { , если (searchKeywords.Contains (outputArray [0])) outputArray.Remove (outputArray [0]); еще outputArray.Remove (outputArray [1]); } – BeingDev

+0

Обновите цикл 'foreach' выше и условный для' outputArray.Count() == 2' и удалите свой последний условный код и он должен работать. Я запустил его с предоставленным примером ввода и получил ожидаемые результаты. – Saggio

0

не уверен, если это правильный ответ, спасибо большое @saggio, для предложений.

private string FormatSearchString(string str) 
    { 
     List<string> searchKeywords = new List<string> { "and", "or" }; 
     //convert to lower case 
     str = str.Replace(",", " ").ToLower(); 

     Regex regex = new Regex(@"[ ]{2,}", RegexOptions.None); 
     //remove extra whitespace with space 
     str = regex.Replace(str, @" "); 

     //split string 
     string[] strArray = str.Split(' '); 

     List<string> outputArray = new List<string>(); 
     string output = ""; 
     string prevStr = ""; 
     string currStr = ""; 
     bool keywordFlag = false; 
     bool duplicateFlag = false; 

     //remove adjacent keyword or same words 
     foreach (var item in strArray) 
     { 
      currStr = item.Trim(); 
      keywordFlag = searchKeywords.Contains(prevStr) && searchKeywords.Contains(currStr); 
      duplicateFlag = outputArray.Contains(currStr) && !searchKeywords.Contains(currStr); 
      if (!currStr.Equals(prevStr) && !keywordFlag && !duplicateFlag) 
      { 
       if (!searchKeywords.Contains(prevStr) && !searchKeywords.Contains(currStr) && prevStr != "") 
       { 
        outputArray.Add("or"); 
       } 
       outputArray.Add(currStr); 
       prevStr = currStr; 
      } 
     } 

     if (outputArray.Count() == 2) 
     { 
      if (searchKeywords.Contains(outputArray[0])) 
       outputArray.Remove(outputArray[0]); 
      else 
       outputArray.Remove(outputArray[1]); 
     } 

     output = string.Join(" ", outputArray); 

     return output; 
    }