簡體   English   中英

C# 正則表達式拆分 - 引號外的逗號

[英]C# Regex Split - commas outside quotes

我得到了很多具有以下格式的字符串(實際上是 SQL 代碼段):

('ABCDEFG', 123542, 'XYZ 99,9')

我需要使用 C# 拆分此字符串,以獲得:

  • 'ABCDEFG'
  • 123542
  • 'XYZ 99,9'

我最初使用的是一個簡單的Split(',') ,但由於最后一個參數中的逗號導致輸出中的破壞,我需要使用正則表達式來獲取它。 問題是我在正則表達式方面仍然很菜鳥,我似乎無法破解該模式,主要是因為在該字符串中,數字和字母數字參數可能隨時存在......

我可以用什么來根據引號外的每個逗號分割該字符串? 干杯

您可以拆分所有逗號,它們后面有偶數個引號,使用以下正則表達式查找它們:

",(?=(?:[^']*'[^']*')*[^']*$)"

你會像這樣使用它

var result = Regex.Split(samplestring, ",(?=(?:[^']*'[^']*')*[^']*$)");
//this regular expression splits string on the separator character NOT inside double quotes. 
//separatorChar can be any character like comma or semicolon etc. 
//it also allows single quotes inside the string value: e.g. "Mike's Kitchen","Jane's Room"
Regex regx = new Regex(separatorChar + "(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))"); 
string[] line = regx.Split(string to split);

雖然有時我也喜歡挑戰,但這實際上不是。 請閱讀這篇文章http://secretgeek.net/csv_trouble.asp然后繼續使用http://www.filehelpers.com/

[Edit1, 3]:或者這篇文章也可以提供幫助(鏈接只顯示了一些 VB.Net 示例代碼,但您仍然可以將它與 C# 一起使用!): http : //msdn.microsoft.com/en-us /圖書館/cakac7e6.aspx

我已經嘗試為 C# 做示例(將 Microsoft.VisualBasic 的引用添加到您的項目中)

using System;
using System.IO;
using Microsoft.VisualBasic.FileIO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            TextReader reader = new StringReader("('ABCDEFG', 123542, 'XYZ 99,9')");
            TextFieldParser fieldParser = new TextFieldParser(reader);

            fieldParser.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited;
            fieldParser.SetDelimiters(",");

            String[] currentRow; 

            while (!fieldParser.EndOfData)
            {
                try
                {
                     currentRow = fieldParser.ReadFields();

                     foreach(String currentField in currentRow)
                     {
                        Console.WriteLine(currentField);                        
                     }
                }
                catch (MalformedLineException e)
                {
                    Console.WriteLine("Line {0} is not valid and will be skipped.", e);
               }

            } 

        }
    }
}

[Edit2]:在這里找到了另一個可能有幫助的: http : //www.codeproject.com/KB/database/CsvReader.aspx

——萊因哈特

我有一個問題,它沒有捕獲空列。 我這樣修改它以獲得空字符串結果

var results = Regex.Split(source, "[,]{1}(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))");

在 split 方法中嘗試(從 Jens' 中竊取):

",(?:.*?'[^']*?')"

或者只是在 Jens 的 * 后面添加問號,這使它變得懶惰而不是貪婪。

...或者您可以安裝 NuGet 包 LumenWorks CsvReader 並完成如下操作,我讀取了一個包含內容的 csv 文件,例如

"hello","how","hello, how are you"
"hi","hello","greetings"
...

並像這樣處理它

public static void ProcessCsv()
        {
            var filename = @"your_file_path\filename.csv";
            DataTable dt = new DataTable("MyTable");

            List<string> product_codes = new List<string>();
            using (CsvReader csv = new CsvReader(new StreamReader(filename), true))
            {
                int fieldCount = csv.FieldCount;

                string[] headers = csv.GetFieldHeaders();
                for (int i = 0; i < headers.Length; i++)
                {
                     dt.Columns.Add(headers[i], typeof(string));
                }

                while (csv.ReadNextRecord())
                {
                    DataRow dr = dt.NewRow();
                    for (int i = 0; i < fieldCount; i++)
                    {
                        product_codes.Add(csv[i]);
                        dr[i] = csv[i];
                    }
                    dt.Rows.Add(dr);
                }
            }
        }

接受的答案對我不起作用(可以在 Regexr-dot-com 上進行測試,然后發現它不起作用)。 所以我不得不將這些行讀入一個行數組。 使用 (C#) Regex.Matches 獲取在轉義引號之間找到的任何字符串的數組(您的字段內逗號應位於用引號括起來的字段中),並將逗號替換為 || 在將每一行拆分為列/字段之前。 分割每一行后,我循環每一行和每一列來替換 || 用逗號。

        private static IEnumerable<string[]> ReadCsv(string fileName, char delimiter = ';')
    {
        string[] lines = File.ReadAllLines(fileName, Encoding.ASCII);
        // Before splitting on comma for a field array, we have to replace commas witin the fields
        for(int l = 1; l < lines.Length; l++)
        {
            //(\\")(.*?)(\\")
            MatchCollection regexGroup2 = Regex.Matches(lines[l], "(\\\")(.*?)(\\\")");
            if (regexGroup2.Count > 0)
            {
                for (int g = 0; g < regexGroup2.Count; g++)
                {
                    lines[l] = lines[l].Replace(regexGroup2[g].Value, regexGroup2[g].Value.Replace(",", "||"));
                }
            }
        }

        // Split
        IEnumerable<string[]> lines_split = lines.Select(a => a.Split(delimiter));

        // Reapply commas
        foreach(string[] row in lines_split)
        {
            for(int c = 0; c < row.Length; c++)
            {
                row[c] = row[c].Replace("||", ",");
            }
        }

        return (lines_split);
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM