如果逗号不在双引号之间,则按逗号分割

3

我想按逗号分隔这样的字符串:

 field1:"value1", field2:"value2", field3:"value3,value4"

将其转换为一个string[]数组,看起来像:
0     field1:"value1"
1     field2:"value2"
2     field3:"value3,value4"

我正在尝试使用Regex.Split来做到这一点,但似乎无法弄清楚正则表达式。


4
在这种情况下,你能否只是按 ", 分割吗? - webnoob
@Webnoob 这也会删除尾随的 ",请注意。 - LukeHennerley
@LukeHennerley - 如果你知道它会丢失,如果需要的话,把它放回去也不是什么大问题。 - webnoob
2
@webnoob 的确是这样,只是要确保人们在发布任何内容之前知道要按照这种方式操作。 - LukeHennerley
不确定您是否可以使用正则表达式完成此操作。但只需扫描字符串即可轻松实现。从开头开始查找逗号。跟踪当前是否在引号字符串中。 - Matt Varblow
@LukeHennerley - 很好的观点。+1。 - webnoob
5个回答

7

使用MatchesSplit更容易实现这个,例如:

string[] asYouWanted = Regex.Matches(input, @"[A-Za-z0-9]+:"".*?""")
    .Cast<Match>()
    .Select(m => m.Value)
    .ToArray();

虽然如果你的值(或字段)包含转义引号(或类似的麻烦字符),那么最好使用适当的CSV解析器。


如果您的值中确实有转义引号,则我认为以下正则表达式将起作用 - 进行测试:

@"field3:""value3\\"",value4""", @"[A-Za-z0-9]+:"".*?(?<=(?<!\\)(\\\\)*)"""

添加的(?<=(?<!\\)(\\\\)*)是为了确保它停止匹配的"之前只有偶数个斜杠,因为奇数个斜杠意味着它被转义。

1

未经测试,但应该没问题:

string[] parts = string.Split(new string[] { ",\"" }, StringSplitOptions.None);

如果需要,记得在末尾添加“反斜杠”。


1
string[] arr = str.Split(new string[] {"\","}}, StringSplitOptions.None).Select(str => str + "\"").ToArray();

按照webnoob所提到的方法,使用\,进行分割,然后在选择时加上尾随的",最后转换为数组。


似乎Split无法将string[]作为参数。 - BuZz
如何聪明地不将“”附加到Linq中的最后一项? - BuZz
@Franklin,请看我的编辑,我认为我漏掉了stringsplitoptions参数。你的第二条评论是什么意思? - LukeHennerley

0
最简单的内置方法是这里。我检查过了,它可以正常工作。它将"Hai,\"Hello,World\""分割成{"Hai","Hello,World"}

0

试一下这个

// (\w.+?):"(\w.+?)"        
//         
// Match the regular expression below and capture its match into backreference number 1 «(\w.+?)»        
//    Match a single character that is a “word character” (letters, digits, and underscores) «\w»        
//    Match any single character that is not a line break character «.+?»        
//       Between one and unlimited times, as few times as possible, expanding as needed (lazy) «+?»        
// Match the characters “:"” literally «:"»        
// Match the regular expression below and capture its match into backreference number 2 «(\w.+?)»        
//    Match a single character that is a “word character” (letters, digits, and underscores) «\w»        
//    Match any single character that is not a line break character «.+?»        
//       Between one and unlimited times, as few times as possible, expanding as needed (lazy) «+?»        
// Match the character “"” literally «"»        


try {        
    Regex regObj = new Regex(@"(\w.+?):""(\w.+?)""");        
    Match matchResults = regObj.Match(sourceString);        
    string[] arr = new string[match.Captures.Count];        
    int i = 0;        
    while (matchResults.Success) {        
        arr[i] = matchResults.Value;        
        matchResults = matchResults.NextMatch();        
        i++;        
    }         
} catch (ArgumentException ex) {        
    // Syntax error in the regular expression        
}

你是不是复制了RegexBodies的解释并粘贴到这里了? - Sebastian Mach
我知道我知道那个俚语 :D - Sebastian Mach

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接