2009-07-03 41 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;