【发布时间】:2012-03-26 07:09:27
【问题描述】:
问题:
我有一个搜索 ODBC 转义序列的函数, 然后递归地用它们的原生等价物替换它们。
例如,给定一个 ODBC 转义序列,如: {fn concat(column1, column2)}
我用它的原生 SQL 等价物替换它
if (StringComparer.OrdinalIgnoreCase.Equals("concat", strFunctionName)) {
strArguments = strArguments;
string[] astrArguments = strArguments.Split(',');
string strTerm = astrArguments[0] + " || " + astrArguments[1];
return strTerm;
}
产生第 1 列 || column2(PostGreSql 语法)
一般来说,我必须将字符串“arglist_comma_separated”解析为 {fn 随便(arglist_comma_separated)}
进入其组件
不用说,在我当前的版本中,它不起作用 如果 arglist 中的参数 1 类似于
'hello, world'
更糟糕的是,如果我将家庭和名字连接起来,例如,它可能是 {fn 不管('d''Amato', 'Alberto')}
如何最好地拆分论点?
如何使用正则表达式或解析来做到这一点?
编辑:
嗯,又想了想,有个绝妙的主意(把''换成转义符)。
这样一来,对于非正则表达式解决方案,问题的复杂性已从中高降低到微不足道:
附录:实际上,几乎是微不足道的,我忘了在拆分中考虑函数嵌套 - 愚蠢。
protected static string[] GetArguments(string strAllArguments)
{
string EscapeCharacter = System.Convert.ToChar(8).ToString();
strAllArguments = strAllArguments.Replace("''", EscapeCharacter);
bool bInString = false;
int iLastSplitAt = 0;
int iInFunction = 0;
System.Collections.Generic.List<string> lsArguments = new System.Collections.Generic.List<string>();
for (int i = 0; i < strAllArguments.Length; i++)
{
char strCurrentChar = strAllArguments[i];
if (strCurrentChar == '\'')
bInString = !bInString;
if (bInString)
continue;
if (strCurrentChar == '(')
iInFunction++;
if (strCurrentChar == ')')
iInFunction--;
if (strCurrentChar == ',')
{
if(iInFunction == 0)
{
string strExtract = strAllArguments.Substring(iLastSplitAt, i - iLastSplitAt);
strExtract = strExtract.Replace(EscapeCharacter, "''");
lsArguments.Add(strExtract);
iLastSplitAt = i;
}
}
}
string strExtractLast = strAllArguments.Substring(iLastSplitAt + 1);
strExtractLast = strExtractLast.Replace(EscapeCharacter, "''");
lsArguments.Add(strExtractLast);
string[] astrResult = lsArguments.ToArray();
lsArguments.Clear();
lsArguments = null;
return astrResult;
}
【问题讨论】:
-
一个类似的问题,结论可能是“不要使用正则表达式”:stackoverflow.com/questions/4150697/…
-
@DavidBrabant 虽然我同意正则表达式不是灵丹妙药,但我想不出更好的方法来处理这种情况。这里的参数符合常规语言(否则 SQL 词法分析器将无法解析它们),因此将它们中的 each 与正则表达式匹配是有意义的。在另一个问题中,OP 想用 一个 正则表达式匹配/拆分它们中的 all,我完全同意你的观点,即 that '不可取。
-
@Quandary +1 您的新解决方案对我来说看起来不错,只要您确保
EscapeCharacter不可能出现在您的原始输入中。我只建议将其移出问题并将其发布as a new answer。
标签: c# sql regex parsing split