2011-05-24 83 views
5

使用C#,我需要使用LIKE命令在SQL Server數據庫中搜索搜索文本,方法是用%字符替換引號外的所有空格。例如:使用正則表達式替換引號之外的空格

輸入:

my "search text" 

輸出:

%my%search text% 

任何幫助,將不勝感激。在替換文本之前,我可以處理帶有奇數引號的輸入字符串。

回答

6

如果使用正則表達式,你可以做到這一點,如果你確保所有引號是正確的平衡,如果沒有逃過字符串中的引號(\")(也可以考慮那些,但它使得正則表達式更加複雜)。

resultString = Regex.Replace(subjectString, 
    @"[\ ]  # Match a space (brackets for legibility) 
    (?=   # Assert that the string after the current position matches... 
    [^""]*  # any non-quote characters 
    (?:   # followed by... 
     ""[^""]* # one quote, followed by 0+ non-quotes 
     ""[^""]* # a second quote and 0+ non-quotes 
    )*   # any number of times, ensuring an even number of quotes 
    $   # until the end of the string 
    )   # End of lookahead", 
    "%", RegexOptions.IgnorePatternWhitespace); 

這將檢查字符串的其餘部分以在當前空格字符後面聲明偶數個引號。 lookahead(感謝Alan Moore!)的優勢在於它比lookbehind更容易移植(除.NET之外的大多數正則表達式,其他一些不支持lookbehind斷言中的無限重複)。它也可能更快。

回顧後,涉及的原始解決方案如下:

resultString = Regex.Replace(subjectString, 
    @"(?<=  # Assert that the string up to the current position matches... 
    ^   # from the start of the string 
    [^""]*  # any non-quote characters 
    (?:   # followed by... 
     ""[^""]* # one quote, followed by 0+ non-quotes 
     ""[^""]* # a second quote and 0+ non-quotes 
    )*   # any number of times, ensuring an even number of quotes 
    )   # End of lookbehind 
    [ ]   # Match a space (brackets for legibility)", 
    "%", RegexOptions.IgnorePatternWhitespace); 
+0

@Andreas:不錯的選擇。您應該接受@ Oded的答案,然後(點擊旁邊的複選標記)。 – 2011-05-27 11:35:10

10

而不是使用RegEx,使用一個簡單的狀態機 - 在每個字符上循環,注意你是在「引入」還是「在引用」之外,只有當你處於「out」狀態時才替換空格。

+0

謝謝,這顯然比正則表達式的方法容易得多。我仍然不得不用一個%替換幾個連續的空格,但這不是很困難(我使用正則表達式完成了這部分)。 – Andreas 2011-05-27 11:08:37

0

如果雙引號不以某種方式逃脫,再下面是另一種可能性。可能不像某些方法那麼高效(當然不像Tim的正則表達式那麼酷),但當下一個人看代碼時,這可能是合理的理解。它將字符串拆分爲雙引號,然後遍歷這些值。奇數條目是引號之外的部分,甚至條目都是引號內的部分。

string value = "\"first\" some text \"other in quotes\" out of them \"in them\""; 
    string[] sets = value.Split('\"'); 
    StringBuilder newvalue = new StringBuilder("%"); 
    for (int i = 0; i < sets.Length; i++) { 
    if (i % 2 == 0) 
     // even ones are outside quotes 
     newvalue.Append(sets[i].Replace(' ', '%')); 
    else 
     // and the odd ones are in quotes 
     newvalue.Append("\"" + sets[i] + "\""); 
    } 

    // final % 
    newvalue.Append("%"); 
0

看起來你也想去掉引號並添加%到搜索字符串的開頭和結尾。試試這個:

string s0 = @"my ""search text"""; 

Regex re = new Regex(@"(?x) 
    (?: 
     (?<term>[^\s""]+) 
    | 
     ""(?<term>[^""]+)"" 
    ) 
    (?:\s+|$)"); 

string s1 = @"%" + re.Replace(s0, @"${term}%"); 
Console.WriteLine(s1); 

輸出:

%my%search text% 
0

會做這樣的事情:

private static string RemoveUnquotedWhiteSpaces(string text) 
{  
    string result = String.Empty; 
    var parts = text.Split('"'); 
    for(int i = 0; i < parts.Length; i++) 
    { 
     if (i % 2 == 0) result += Regex.Replace(parts[i], " ", ""); 
     else result += String.Format("\"{0}\"", parts[i]); 
    } 
    return result 
    } 
相關問題