2011-05-24 24 views
5

C# 'yı kullanarak,% s karakteri ile tüm boşlukları dışarıda bırakarak LIKE komutunu kullanarak SQL Server veritabanında arama yapmak için bir arama metni hazırlamalıyım. Örnek:Normal ifadeyi kullanarak boşlukların dışındaki tırnakları değiştirin

Girdi:

my "search text" 

Çıkış: Herhangi bir yardım takdir

%my%search text% 

. Metni değiştirmeden önce giriş dizelerini tek bir tırnak işareti ile işleyebilirim.

cevap

6

Bir düzenli ifade kullanmak sahip Eğer tüm tırnak doğru dengeli ve varsa hiçbir dizede tırnak (\") kaçan eminseniz, bunu yapabilirsiniz (o hesaba mümkündür Ayrıca, bu regex'i daha da karmaşık hale getirir.

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); 

Bu akım uzay karakterinden sonra tırnak çift sayıda savunmak için dize kalanını inceler. Lookahead'ın avantajı (teşekkürler Alan Moore!), Lookbehind'den daha portatiftir (.NET dışındaki çoğu regex çeşidi ve bir kaç diğerleri de lookbehind iddiaları içinde belirsiz tekrarlamayı desteklememektedir). Aynı zamanda daha hızlı olabilir. aşağıdaki gibi

modelleri geriye dönük karıştığı orijinal çözümdür:

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: İyi seçim. @ Oded'in cevabını kabul etmelisiniz, sonra (yanındaki onay işaretini tıklayın). –

10

RegEx kullanmak yerine, her karakterin üzerinde basit bir durum döngüsü - kullanın, tırnakların "içinde" veya "dışarıda" olup olmadığına dikkat edin ve yalnızca "çıkış" durumundayken boşlukları değiştirin.

+0

sayesinde bu görünüşte regex yaklaşımı çok daha kolay oldu. Birkaç ardışık beyaz alanı bir% ile değiştirmek zorunda kaldım ama bu çok zor değil (bu kısmı regex kullanarak yaptım). – Andreas

0

çift tırnak bazı moda çıkışı yapılmaz, o zaman aşağıdaki başka bir olasılıktır. Muhtemelen bazı yöntemler kadar etkili değil (ve kesinlikle Tim'in regex kadar serin değil), ama bir sonraki adam kodu göründüğünde makul anlaşılır olabilir. Dizeyi çift tırnak üzerine böler ve ardından değerler arasında dolaşır. Tek girişler tırnakların dışındaki kısımlardır, hatta girişler tırnak içine girer. Ayrıca tırnak işaretlerini kaldırmak ve arama dizesinin başına ve sonuna bir % eklemek istediğiniz gibi

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

görünüyor. Bu deneyin:

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

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

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

çıkışı:

%my%search text% 
0

böyle bir şey yaparlar mıydı:

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 
    } 
İlgili konular