2009-07-03 101 views
3

真正簡單的問題:分割而佔轉義字符的字符串用分號

我想一個連接字符串分割成它的鍵/值對,因此,例如下面的連接字符串:

Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=vm-jp-dev2;Data Source=scsql\sql2005;Auto Translate=False 

將成爲:

Provider=SQLOLEDB.1 
Integrated Security=SSPI 
Persist Security Info=False 
Initial Catalog=vm-jp-dev2 
Data Source=scsql\sql2005 
Auto Translate=False 

麻煩的是,MSDN documentation指出連接字符串值都允許包含分號如果VAL UE用單或雙引號字符,(所以如果我的理解以下將是有效的):

Provider="Some;Provider";Initial Catalog='Some;Catalog';... 

請告訴我分裂的最佳途徑此字符串(在C#)?

回答

9

有一個DBConnectionStringBuilder類,將你想要做什麼......

 System.Data.Common.DbConnectionStringBuilder builder = new System.Data.Common.DbConnectionStringBuilder(); 

     builder.ConnectionString = "Provider=\"Some;Provider\";Initial Catalog='Some;Catalog';"; 

     foreach (string key in builder.Keys) 
     { 
      Response.Write(String.Format("{0}: {1}<br>", key , builder[key])); 
     } 
+0

謝謝,我覺得有可能是這樣的THI但我找不到它! – Justin 2009-07-03 13:01:23

0

你應該實現某種簡單的字符串解析引用引號。類似的東西:

public static IEnumerable<string> SplitString(string str) 
{ 
    int StartIndex = 0; 
    bool IsQuoted = false; 
    for (int I = 0; I < str.Length; I++) 
    { 
     if (str[I] == '"') 
      IsQuoted = !IsQuoted; 
     if ((str[I] == ';') && !IsQuoted) 
     { 
      yield return str.Substring(StartIndex, I - StartIndex);   
      StartIndex = I + 1; 
     } 
    } 

    if (StartIndex < str.Length) 
     yield return str.Substring(StartIndex); 
} 
0

你可以寫一個迷你分析器。在字符串中移動以跟蹤引用狀態。一般來說可能更可靠。

另一種選擇是使用一個正則表達式,而整個內容,它可以在一個regex.Split被捕獲,而不是跳過輸出相匹配:

var re = new Regex(@"([\w\s]+=\s*?(?:['""][\w\s]+['""]|[\w\s]+));"); 
var parts = re.Split(connectionString) 

這假定:

  • 否引用引號(或其他方式)引號的能力
  • 名稱上的內容僅限於空格和字母數字(用覆蓋有效字符的組替換[\ s \ w])。

就個人而言,如果我不能很快鍛鍊正則表達式,我會去解析器。

編輯:有一個更簡單的方法。 DbConnectionStringBuilder實現IEnumerable,所以把它做的工作:

using System; 
using System.Collections.Generic; 
using System.Data.Common; 

class Program { 
    static void Main(string[] args) { 
     string conStr = @"Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=vm-jp-dev2;Data Source='scsql\sql;2005';Auto Translate=False"; 

     var cb = new DbConnectionStringBuilder(); 
     cb.ConnectionString = conStr; 
     int n = 0; 
     foreach (KeyValuePair<string, object> c in cb) { 
      Console.WriteLine("#{0}: {1}={2}", ++n, c.Key, c.Value); 
     } 
    } 
} 
0

在SQL Server中,你可以簡單地做的情況下:

SqlConnectionStringBuilder decoder = new SqlConnectionStringBuilder(connectionString); 

string UserID = decoder.UserID; 
string Password = decoder.Password;