我有一个(吨)string
(s)这样:
HKR,Drivers,SubClasses,,"wave,midi,mixer,aux"
我基本上希望在strings
字符处将其拆分为多个,
。
但是,如果,
字符位于"
内或%
内,则应忽略该字符。
换句话说,从上面的一行开始,我期待字符串:
HKR
Drivers
SubClasses
"wave,midi,mixer,aux"
(上面一个空行表示一个空字符串)。
如果该行是HKR,Drivers,SubClasses,,%wave,midi,mixer,aux%
,那么基本上与上面相同,当然只有最后一个要返回的字符串应为%wave,midi,mixer,aux%
。
我有一些正常工作的代码,但是 令人难以置信地处理所有行的速度很慢,而且我非常需要找到一种更快的方法来执行此操作。
private static IEnumerable<string> GetValues(string line)
{
var insideQuotes = false;
var insidePercent = false;
var startValueIndex = 0;
for (var i = 0; i < line.Length; i++)
{
if (line[i] == '%' && !insideQuotes)
{
insidePercent = !insidePercent;
}
if (line[i] == '"')
{
insideQuotes = !insideQuotes;
}
if (line[i] != ',' || insideQuotes || insidePercent)
{
continue;
}
yield return line.Substring(startValueIndex, i - startValueIndex);
startValueIndex = i + 1;
}
}
任何帮助都将不胜感激。
答案 0 :(得分:1)
使用VisualBasic.TextFieldParser
并将HasFieldsEnclosedInQuotes
设置为true
。
我会使用像这样的方法一次处理所有行:
public static IEnumerable<string[]> GetValues(string allLines)
{
using (var parser = new Microsoft.VisualBasic.FileIO.TextFieldParser(new StringReader(allLines)))
{
parser.HasFieldsEnclosedInQuotes = true;
parser.Delimiters = new[] { "," };
while (!parser.EndOfData)
{
string[] nextLineFields = parser.ReadFields();
yield return nextLineFields;
}
}
}
您的样本:
var allLinesFields = GetValues("HKR,Drivers,SubClasses,,\"wave, midi, mixer, aux\"");
foreach (string[] lineFields in allLinesFields)
Console.WriteLine(string.Join(Environment.NewLine, lineFields));
它将比String.Split
更有效,并且还支持您可能甚至没有想过的其他事情。如果格式无效,您还可以处理特殊例外。
答案 1 :(得分:0)
我刚刚重新排序了一些查询语句以避免字符串操作。这应该更有效率。
private static IEnumerable<string> GetValues2(string line)
{
bool insideQuotes = false;
bool insidePercent = false;
int startValueIndex = 0;
for (int i = 0; i < line.Length; i++)
{
if (!insideQuotes && line[i] == '%')
{
insidePercent = !insidePercent;
}
if (line[i] == '"')
{
insideQuotes = !insideQuotes;
}
if (insideQuotes || insidePercent || line[i] != ',')
{
continue;
}
yield return line.Substring(startValueIndex, i - startValueIndex);
startValueIndex = i + 1;
}
}