用分号分割字符串,同时考虑转义字符
-
21-08-2019 - |
题
非常简单的问题:
我想将连接字符串拆分为其关键字/值对,例如以下连接字符串:
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 文档 声明如果连接字符串值用单引号或双引号字符括起来,则允许包含分号(因此,如果我理解它,则以下内容将是有效的):
Provider="Some;Provider";Initial Catalog='Some;Catalog';...
分割该字符串的最佳方法是什么(在 C# 中)?
解决方案
有一个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]));
}
其他提示
您应该实现某种简单的字符串解析respecing引号。类似的东西:
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);
}
您可以编写一个小型解析器。在字符串中移动并跟踪引用状态。一般来说可能更可靠。
另一种选择是使用正则表达式,并匹配整个内容,可以在 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);
}
}
}
在SQL Server的情况下,你可以简单地做:
SqlConnectionStringBuilder decoder = new SqlConnectionStringBuilder(connectionString);
string UserID = decoder.UserID;
string Password = decoder.Password;
等
不隶属于 StackOverflow