用逗号分割字符串,忽略引号中的任何标点符号(包括',')

本文关键字:标点符号 任何 包括 字符串 分割 | 更新日期: 2023-09-27 18:19:12

如何通过逗号来分割字符串(从文本框),不包括双引号中的 (而不去掉引号),以及其他可能的标点符号(例如:"。’;' ' - ' ')?

。如果有人在文本框中输入了以下内容:

apple, orange, "baboons, cows", rainbow, "unicorns, gummy bears"

我如何将上面的字符串分成下面的字符串(比如,分成一个List)?

apple
orange
"baboons, cows"
rainbow
"Unicorns, gummy bears..."

谢谢你的帮助!

用逗号分割字符串,忽略引号中的任何标点符号(包括',')

你可以试试下面的正则表达式,

string value = @"apple, orange, ""baboons, cows"", rainbow, ""unicorns, gummy bears""";
string[] lines = Regex.Split(value, @", (?=(?:""[^""]*?(?: [^""]*)*))|, (?=[^"",]+(?:,|$))");
foreach (string line in lines) {
Console.WriteLine(line);
}
输出:

apple
orange
"baboons, cows"
rainbow
"unicorns, gummy bears"

IDEONE

试试这个:

Regex str = new Regex("(?:^|,)('"(?:[^'"]+|'"'")*'"|[^,]*)", RegexOptions.Compiled);
foreach (Match m in str.Matches(input))
{
    Console.WriteLine(m.Value.TrimStart(','));
}

你也可以试着看看FileHelpers

与CSV解析器(而不是Regex)非常相似,您可以遍历每个字符,如下所示:

public List<string> ItemStringToList(string inputString)
{  
    var itemList   = new List<string>();
    var currentIem = "";
    var quotesOpen = false;
    for (int i = 0; i < inputString.Length; i++)
    {
        if (inputString[i] == '"')
        {
            quotesOpen = !quotesOpen;
            continue;
        }
        if (inputString[i] == ',' && !quotesOpen)
        {
            itemList.Add(currentIem);
            currentIem = "";
            continue;
        }
        if (currentIem == "" && inputString[i] == ' ') continue;
        currentIem += inputString[i];
    }
    if (currentIem != "") itemList.Add(currentIem);
    return itemList;
}

示例测试用法:

var test1 = ItemStringToList("one, two, three");
var test2 = ItemStringToList("one, '"two'", three");
var test3 = ItemStringToList("one, '"two, three'"");
var test4 = ItemStringToList("one, '"two, three'", four, '"five six'", seven");
var test5 = ItemStringToList("one, '"two, three'", four, '"five six'", seven");
var test6 = ItemStringToList("one, '"two, three'", four, '"five six, seven'"");
var test7 = ItemStringToList("'"one, two, three'", four, '"five six, seven'"");

如果你想要更快的字符连接,你可以把它改成StringBuilder

试试这个,它可以用很多方法分割数组字符串,如果你想用空格分割,只要在(' ')中加一个空格。

  namespace LINQExperiment1
  {
  class Program
  {
  static void Main(string[] args)
  {
   string[] sentence = new string[] { "apple", "orange", "baboons  cows", " rainbow", "unicorns  gummy bears" };
  Console.WriteLine("option 1:"); Console.WriteLine("————-");
  // option 1: Select returns three string[]’s with
  // three strings in each.
  IEnumerable<string[]> words1 =
  sentence.Select(w => w.Split(' '));
  // to get each word, we have to use two foreach loops
  foreach (string[] segment in words1)
  foreach (string word in segment)
  Console.WriteLine(word);
  Console.WriteLine();
  Console.WriteLine("option 2:"); Console.WriteLine("————-");
  // option 2: SelectMany returns nine strings
  // (sub-iterates the Select result)
  IEnumerable<string> words2 =
  sentence.SelectMany(segment => segment.Split(','));
  // with SelectMany we have every string individually
  foreach (var word in words2)
  Console.WriteLine(word);
  // option 3: identical to Opt 2 above written using
  // the Query Expression syntax (multiple froms)
  IEnumerable<string> words3 =from segment in sentence
  from word in segment.Split(' ')
  select word;
   }
  }
 }

这比我想象的要棘手,我认为这是一个很好的实际问题。

下面是我想到的解决方案。对于我的解决方案,我不喜欢的一点是必须在后面加上双引号,另一个是变量名:p:

internal class Program
{
    private static void Main(string[] args)
    {
        string searchString =
            @"apple, orange, ""baboons, cows. dogs- hounds"", rainbow, ""unicorns, gummy bears"", abc, defghj";
        char delimeter = ',';
        char excludeSplittingWithin = '"';
        string[] splittedByExcludeSplittingWithin = searchString.Split(excludeSplittingWithin);
        List<string> splittedSearchString = new List<string>();
        for (int i = 0; i < splittedByExcludeSplittingWithin.Length; i++)
        {
            if (i == 0 || splittedByExcludeSplittingWithin[i].StartsWith(delimeter.ToString()))
            {
                string[] splitttedByDelimeter = splittedByExcludeSplittingWithin[i].Split(delimeter);
                for (int j = 0; j < splitttedByDelimeter.Length; j++)
                {
                    splittedSearchString.Add(splitttedByDelimeter[j].Trim());
                }
            }
            else
            {
                splittedSearchString.Add(excludeSplittingWithin + splittedByExcludeSplittingWithin[i] +
                                         excludeSplittingWithin);
            }
        }
        foreach (string s in splittedSearchString)
        {
            if (s.Trim() != string.Empty)
            {
                Console.WriteLine(s);
            }
        }
        Console.ReadKey();
    }
}

另一个正则表达式解决方案:

private static IEnumerable<string> Parse(string input)
{
  // if used frequently, should be instantiated with Compiled option
  Regex regex = new Regex(@"(?<=^|,'s)('""(?:[^'""]|'""'"")*'""|[^,'s]*)");
  return regex.Matches(inputData).Where(m => m.Success);
}