2010-07-09 6 views
1

좀 검색과 같이 쿼리가 있습니다Howto : C# 문자열을 SQL 전체 텍스트 카탈로그 검색으로 변환 하시겠습니까?

조지 AND NOT 워싱턴 OR 아브라함

개 또는 고양이를 AND NOT 내가 에 대한 결과를 다시 얻고 싶은 것이 검색어

늑대 조지 또는 아브라함은 아니지만 워싱턴

기본적으로 문자열을 가져 와서 문맥 검색을 m y 전체 텍스트 카탈로그 저장 프로 시저 검색.

나는 Regex를 사용해야한다고 가정하고 있지만 Regex는 C#에 익숙하지 않다.

나는이 작업을 수행해야한다고 생각하는 http://support.microsoft.com/kb/246800을 찾았지만 구현에 대한 도움이 필요하다고 생각했습니다.

당신은 매개 변수로 문자열을 받아 문자열을 반환하고자하는 가정 :

string input = 'George Washington AND NOT Martha OR Dog'; 

private string interpretSearchQuery(input) 
{ 
    // HALP! 

     /* replace ' AND ' | ' AND NOT ' with 
     * " AND " 
     * " AND NOT " 
     * 
     * replace ' OR ' | ' OR NOT ' with 
     * " OR " 
     * " OR NOT " 
     * 
     * add " to beginning of string and " to end of string 
     */ 

    return '"George Washington" AND NOT "Martha" OR "Dog"'; 
} 
+0

'interpretSearchQuery'는 정확히 무엇을해야합니까? 입력은 무엇입니까? 예상되는 결과는 무엇입니까? – Oded

+0

나는 공간에 그것을 분할하고 싶지 않았거나 그렇지 않은 배열 항목은 "LIKE '%"앞에 붙이고 "%"를 덧붙여서 공백 문자와 함께 다시 채 웁니다. SQL 쿼리. 글쎄, 실제로 이런 일은하지 않겠지 만, 누가 알지? 그냥 작동 할 수도 있습니다. – Fosco

+0

@Oded 추가 정보를 추가했습니다. 죄송합니다. 기본적으로 나는 입력을 받아서 Sql Server 전체 텍스트 검색에서 적절한 결과를 얻는 데 사용할 수있는 방식으로 변환하려고합니다. – samandmoore

답변

4

나는 당신의 Postfix notation를 사용하여 문자열 (또는 폴란드어 표기법) 구문 분석.

**Postfix algorithm** 
The algorithm for evaluating any postfix expression is fairly straightforward: 

While there are input tokens left  

    Read the next token from input. 

    If the token is a value 
    Push it onto the stack. 

    Otherwise, the token is an operator (operator here includes both operators, and functions). 
    It is known a priori that the operator takes n arguments. 

    If there are fewer than n values on the stack 
    (Error) The user has not input sufficient values in the expression. 
    Else, Pop the top n values from the stack. 

    Evaluate the operator, with the values as arguments. 
    Push the returned results, if any, back onto the stack. 

If there is only one value in the stack 
    That value is the result of the calculation. 

If there are more values in the stack 
    (Error) The user input has too many values. 

그래서 당신의 입력 문자열 복용 :

'조지 워싱턴 AND NOT 마사 OR 개'

을 그리고 그것을 simplifing :

A = George 
B = Washington 
C = Martha 
D = Dog 
& = AND 
! = NOT 
| = OR 
우리가 얻을 것

접미사 표기법은

입니다.

AB & C! D | 수단

:

  1. 푸시 값 A (조지)
  2. 푸시 값 B (워싱턴)
  3. 이전 두 값 터지는하고 결과를 밀어 (조지 AND 워싱턴)
  4. 푸시 값 C (Martha)
  5. 이전 두 값 을 터뜨리고 결과를 푸시하지 않고 (George AND 워싱턴) NOT (마사)
  6. 푸시 값 D (개)
  7. 또는 이전의 두 값 을 보여주고 그 결과 ((조지와 워싱턴 밀어) NOT (마사)) OR (개)
+0

이것은 처음에 생각했던 것입니다. 대신 정규 표현식으로 대신 할 수있는 좋은 방법이되기를 바랍니다. – samandmoore

+0

쿼리 문자열을 취하고 후위 배열을 반환하는 빠른 구문 분석기를 작성한 후에는 쿼리를 매우 간단하게 수행 할 수 있습니다. – GalacticJello

+0

저는이 방법을 사용하려고합니다. 매우 지능적인 솔루션입니다. – samandmoore

3

이것은 당신을 시작할지도 모릅니다 ... 나는 이것을 더 강력하게 만들기 위해 이것으로부터 리팩토링합니다.

string input = "George Washington AND NOT Martha OR Dog"; 

private string interpretSearchQuery(string input) 
{ 
    StringBuilder builder = new StringBuilder(); 
    var tokens = input.Split(' '); 

    bool quoteOpen = false; 
    foreach(string token in tokens) 
    { 
     if(!quoteOpen && !IsSpecial(token)) 
     { 
      builder.AppendFormat(" \"{0}", token); 
      quoteOpen = true; 
     } 
     else if(quoteOpen && IsSpecial(token)) 
     { 
      builder.AppendFormat("\" {0}", token); 
      quoteOpen = false; 
     } 
     else 
     { 
      builder.AppendFormat(" {0}", token); 
     } 
    } 

    if(quoteOpen) 
    { 
     builder.Append("\""); 
    } 

    return "'" + builder.ToString().Trim() + "'"; 
} 

public static bool IsSpecial(string token) 
{ 
    return string.Compare(token, "AND", true) == 0 || 
     string.Compare(token, "OR", true) == 0 || 
     string.Compare(token, "NOT", true) == 0; 
} 
+0

당신의 컨셉이 저를 고무 시켰습니다. postfix를 사용하는 것이 내 솔루션이 완벽하지는 않지만 일을 끝내게됩니다. – samandmoore

+0

@samandmoore 나는 후위 응답을 선택했을 것이다! 이 해킹보다 훨씬 나은 '일반적인'해결책입니다. –

0

다음은 내가 생각해 낸 해결책입니다. 지금 GalacticJello 제안 후위 알고리즘을 구현하는 방법에 대한 이동합니다

private string interpretSearchTerm(string searchTerm) 
     { 
      string term = ""; 
      /* replace ' AND ' | ' AND NOT ' with 
      * " AND " 
      * " AND NOT " 
      * 
      * replace ' OR ' | ' OR NOT ' with 
      * " OR " 
      * " OR NOT " 
      * 
      * add " to beginning of string and " to end of string 
      */ 
      if (searchTerm.IndexOf("AND") > -1 
       || searchTerm.IndexOf("OR") > -1 
       || searchTerm.IndexOf("AND NOT") > -1 
       || searchTerm.IndexOf("OR NOT") > -1) 
      { 
       term = searchTerm.Replace(" AND NOT ", "\"AND NOT\"") 
         .Replace(" AND ", "\"AND\"") 
         .Replace(" OR NOT", "\"OR NOT\"") 
         .Replace(" OR ", "\"OR\""); 
       term = "\"" + term + "\""; 
       return term; 
      } 
      else if (searchTerm.IndexOf("\"") > -1) return searchTerm; 
      else return "\"" + searchTerm + "\""; 
     } 

: 유일한 문제는 잘못된 검색 쿼리가 제대로 구문 분석하고 실패하지 않을 것입니다. 나는 그것을 작동시킬 때 그것을 게시 할 것이다.

관련 문제