Fri*_*les 11 c# regex escaping delimiter
我有一个管道分隔文件,我想拆分(我正在使用C#).例如:
This|is|a|test
但是,某些数据可能包含管道.如果是,它将使用反斜杠进行转义:
This|is|a|pip\|ed|test (this is a pip|ed test)
我想知道是否有一个正则表达式或其他方法将它拆分为仅仅"纯"管道(即在它们前面没有反斜杠的管道).我当前的方法是使用自定义位文本替换转义的管道,拆分管道,然后用管道替换我的自定义文本.不是很优雅,我不禁想到有更好的方法.谢谢你的帮助.
只是String.IndexOf()用来找到下一个管道.如果前一个字符不是反斜杠,则使用String.Substring()提取单词.或者,您可以使用 String.IndexOfAny()查找管道或反斜杠的下一个匹配项.
我做了很多像这样的解析,这真的很直接.采取我的方法,如果正确完成也会更快地运行.
编辑
事实上,也许是这样的.看看这与RegEx解决方案在性能方面的比较会很有趣.
public List<string> ParseWords(string s)
{
List<string> words = new List<string>();
int pos = 0;
while (pos < s.Length)
{
// Get word start
int start = pos;
// Get word end
pos = s.IndexOf('|', pos);
while (pos > 0 && s[pos - 1] == '\\')
{
pos++;
pos = s.IndexOf('|', pos);
}
// Adjust for pipe not found
if (pos < 0)
pos = s.Length;
// Extract this word
words.Add(s.Substring(start, pos - start));
// Skip over pipe
if (pos < s.Length)
pos++;
}
return words;
}
Run Code Online (Sandbox Code Playgroud)
这应该这样做:
string test = @"This|is|a|pip\|ed|test (this is a pip|ed test)";
string[] parts = Regex.Split(test, @"(?<!(?<!\\)*\\)\|");
Run Code Online (Sandbox Code Playgroud)
正则表达式基本上说:在前面没有转义字符的管道上拆分。不过,我不应该为此承担任何责任,我只是从这篇文章中劫持了正则表达式并对其进行了简化。
编辑
在性能方面,对比本线程提供的手动解析方法,我发现这个Regex实现比Jonathon Wood使用OP提供的更长测试字符串的实现慢了3到5倍。
话虽如此,如果您不实例化或将单词添加到 aList<string>并返回 void,则 Jon 的方法比Regex.Split()纯粹拆分字符串的方法(0.01 毫秒与 0.002 毫秒)快约 5 倍。如果你加上管理和返回 a 的开销List<string>,它大约快 3.6 倍(0.01 毫秒对 0.00275 毫秒),平均超过几百万次迭代。我没有在这个测试中使用静态 Regex.Split() ,而是使用上面的表达式在我的测试循环之外创建了一个新的 Regex 实例,然后调用它的 Split 方法。
更新
使用静态 Regex.Split() 函数实际上比重用表达式的实例要快得多。使用此实现,使用正则表达式仅比 Jon 的实现慢 1.6 倍(0.0043ms vs. 0.00275ms)
使用我链接到的帖子中的扩展正则表达式,结果是一样的。