【问题标题】:Split by comma if that comma is not located between two double quotes如果逗号不在两个双引号之间,则用逗号分隔
【发布时间】:2012-12-17 14:17:53
【问题描述】:

我希望用逗号分割这样的字符串:

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

变成string[],看起来像:

0     field1:"value1"
1     field2:"value2"
2     field3:"value3,value4"

我正在尝试使用 Regex.Split 执行此操作,但似乎无法计算出正则表达式。

【问题讨论】:

  • 在这种情况下你不能直接在",上拆分吗?
  • @webnoob 这也将删除尾随的",请记住。
  • @LukeHennerley - 如果你知道它会丢失,如果需要的话,把它放回去也没什么。
  • @webnoob 确实是这样,只是在发布任何内容之前确保人们知道这样做。
  • 不确定您是否可以使用正则表达式执行此操作。但是只扫描字符串不会太难。从头开始并寻找逗号。跟踪您当前是否在带引号的字符串中。

标签: c# regex


【解决方案1】:

例如,使用Matches 比使用Split 更容易做到这一点

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

虽然如果您的值(或字段!)有任何机会包含转义引号(或任何类似棘手的东西),那么使用适当的 CSV 解析器可能会更好。


如果您确实在您的值中转义了引号,我认为以下正则表达式 工作 - 给它一个测试:

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

添加的(?&lt;=(?&lt;!\\)(\\\\)*) 应该确保它停止匹配的" 前面只有偶数个斜线,因为奇数个斜线意味着它被转义。

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:
      string[] arr = str.Split(new string[] {"\","}}, StringSplitOptions.None).Select(str => str + "\"").ToArray();
      

      如 webnoob 所述,由\, 拆分,然后使用 select 以 " 结尾,然后转换为数组。

      【讨论】:

      • 好像Split不能把string[]作为参数
      • 如何智能地不将 " 附加到 Linq 中的最后一项?
      • @Franklin 看到我的编辑,我想我错过了 stringsplitoptions 参数。我不明白你说的第二条评论是什么意思?
      【解决方案4】:

      试试这个

      // (\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的解释复制到这里了吗?
      • 我知道我知道俚语:D
      【解决方案5】:

      最简单的内置方法是here。我查过了。它工作正常。它将"Hai,\"Hello,World\"" 拆分为{"Hai","Hello,World"}

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-01-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多