除了用双引号括起来之外,在逗号(,)上拆分的正则表达式是什么?例如:
max,emily,john = ["max", "emily", "john"]
BUT
max,"emily,kate",john = ["max", "emily,kate", "john"]
希望在C#中使用:Regex.Split(string, "PATTERN-HERE");
感谢。
答案 0 :(得分:14)
这样的情况通常需要除正则表达式之外的其他东西。它们很漂亮,但处理这种事情的模式比它们有用的更复杂。
您可以尝试这样的事情:
public static IEnumerable<string> SplitCSV(string csvString)
{
var sb = new StringBuilder();
bool quoted = false;
foreach (char c in csvString) {
if (quoted) {
if (c == '"')
quoted = false;
else
sb.Append(c);
} else {
if (c == '"') {
quoted = true;
} else if (c == ',') {
yield return sb.ToString();
sb.Length = 0;
} else {
sb.Append(c);
}
}
}
if (quoted)
throw new ArgumentException("csvString", "Unterminated quotation mark.");
yield return sb.ToString();
}
可能需要进行一些调整才能完全遵循CSV规范,但基本逻辑是合理的。
答案 1 :(得分:1)
对于CSV解析器来说,这是一个明确的案例,因此您应该使用.NET自己的CSV解析功能或cdhowie的解决方案。
纯粹是为了您的信息而不是一个可行的解决方案,以下是使用Regex.Split()
的正则表达式时必须经历的扭曲:
您可以使用正则表达式(请不要!)
(?<=^(?:[^"]*"[^"]*")*[^"]*) # assert that there is an even number of quotes before...
\s*,\s* # the comma to be split on...
(?=(?:[^"]*"[^"]*")*[^"]*$) # as well as after the comma.
如果您的引用字符串从不包含转义引号,和您不介意引号本身成为匹配的一部分。
这非常低效,读取和调试很痛苦,只能在.NET中运行,并且在转义引号上失败(至少如果你没有使用""
来逃避单引号)。当然可以修改正则表达式 来处理它,但那时它将是完全可怕的。
答案 2 :(得分:0)
可能有点晚,但我希望我可以帮助别人
String[] cols = Regex.Split("max, emily, john", @"\s*,\s*");
foreach ( String s in cols ) {
Console.WriteLine(s);
}
答案 3 :(得分:0)
贾斯汀,重新提出这个问题,因为它有一个简单的正则表达式解决方案,没有提到。这种情况直接来自Match (or replace) a pattern except in situations s1, s2, s3 etc。
这是我们简单的正则表达式:
"[^"]*"|(,)
交替的左侧匹配完整的"quoted strings"
标签。我们将忽略这些匹配。右侧匹配并捕获第1组的逗号,我们知道它们是正确的逗号,因为它们与左侧的表达式不匹配。我们将这些逗号替换为SplitHere
,然后我们将其分为SplitHere
。
此程序显示了如何使用正则表达式(请参阅online demo底部的结果):
using System;
using System.Text.RegularExpressions;
using System.Collections.Specialized;
class Program
{
static void Main() {
string s1 = @"max,""emily,kate"",john";
var myRegex = new Regex(@"""[^""]*""|(,)");
string replaced = myRegex.Replace(s1, delegate(Match m) {
if (m.Groups[1].Value == "") return m.Value;
else return "SplitHere";
});
string[] splits = Regex.Split(replaced,"SplitHere");
foreach (string split in splits) Console.WriteLine(split);
Console.WriteLine("\nPress Any Key to Exit.");
Console.ReadKey();
} // END Main
} // END Program
参考
How to match (or replace) a pattern except in situations s1, s2, s3...