linq 将分隔符转换为固定宽度的最佳方法

piok6c0g  于 2023-02-10  发布在  其他
关注(0)|答案(6)|浏览(152)

什么是最好的方法来转换这个:

FirstName,LastName,Title,BirthDate,HireDate,City,Region
Nancy,Davolio,Sales Representative,1948-12-08,1992-05-01,Seattle,WA
Andrew,Fuller,Vice President Sales,1952-02-19,1992-08-14,Tacoma,WA
Janet,Leverling,Sales Representative,1963-08-30,1992-04-01,Kirkland,WA
Margaret,Peacock,Sales Representative,1937-09-19,1993-05-03,Redmond,WA
Steven,Buchanan,Sales Manager,1955-03-04,1993-10-17,London,NULL
Michael,Suyama,Sales Representative,1963-07-02,1993-10-17,London,NULL
Robert,King,Sales Representative,1960-05-29,1994-01-02,London,NULL
Laura,Callahan,Inside Sales Coordinator,1958-01-09,1994-03-05,Seattle,WA
Anne,Dodsworth,Sales Representative,1966-01-27,1994-11-15,London,NULL

改为:

FirstName  LastName             Title                          BirthDate   HireDate   City            Region
---------- -------------------- ------------------------------ ----------- ---------- --------------- ---------------
Nancy      Davolio              Sales Representative           1948-12-08  1992-05-01  Seattle         WA
Andrew     Fuller               Vice President, Sales          1952-02-19  1992-08-14  Tacoma          WA
Janet      Leverling            Sales Representative           1963-08-30  1992-04-01  Kirkland        WA
Margaret   Peacock              Sales Representative           1937-09-19  1993-05-03  Redmond         WA
Steven     Buchanan             Sales Manager                  1955-03-04  1993-10-17  London          NULL
Michael    Suyama               Sales Representative           1963-07-02  1993-10-17  London          NULL
Robert     King                 Sales Representative           1960-05-29  1994-01-02  London          NULL
Laura      Callahan             Inside Sales Coordinator       1958-01-09  1994-03-05  Seattle         WA
Anne       Dodsworth            Sales Representative           1966-01-27  1994-11-15  London          NULL
fumotvh3

fumotvh31#

我会创建一个自定义类来保存信息,然后对CSV文件中的每一行执行一个循环,在逗号处拆分并填充自定义对象,然后将它们全部放入一个列表或IEnumable中,并将其放入repeater / datagrid中。

public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Title { get; set; }
        public DateTime BirthDate { get; set; }
        public DateTime HireDate { get; set; }
        public string City { get; set; }
        public string Region { get; set; }
    }

    public void Parse(string csv)
    {
        string[] lines = csv.Split( Environment.NewLine.ToCharArray() );
                    List<Person> persons = new List<Person>();

        foreach (string line in lines)
        {
            string[] values = line.Split( ',' );

            Person p = new Person();

            p.FirstName = values[ 0 ];
            p.LastName = values[ 1 ];

                            persons.Add( p );
            //.... etc etc
        }
    }
ix0qys7i

ix0qys7i2#

这符合您所陈述的要求,并使用LINQ(因为您的问题被标记为LINQ),但不一定是 * 最佳 *:

class Program
{
    static void Main(string[] args)
    {
        List<string> inputs = new List<string>
        {
            "FirstName,LastName,Title,BirthDate,HireDate,City,Region",
            "Nancy,Davolio,Sales Representative,1948-12-08,1992-05-01,Seattle,WA",
            "Andrew,Fuller,Vice President Sales,1952-02-19,1992-08-14,Tacoma,WA",
            "Janet,Leverling,Sales Representative,1963-08-30,1992-04-01,Kirkland,WA",
            "Margaret,Peacock,Sales Representative,1937-09-19,1993-05-03,Redmond,WA",
            "Steven,Buchanan,Sales Manager,1955-03-04,1993-10-17,London,NULL",
            "Michael,Suyama,Sales Representative,1963-07-02,1993-10-17,London,NULL",
            "Robert,King,Sales Representative,1960-05-29,1994-01-02,London,NULL",
            "Laura,Callahan,Inside Sales Coordinator,1958-01-09,1994-03-05,Seattle,WA",
            "Anne,Dodsworth,Sales Representative,1966-01-27,1994-11-15,London,NULL"
        };

        // TODO: These widths would presumably be configurable
        List<int> widths = new List<int> { 12, 22, 32, 13, 12, 17, 8 };

        List<string> outputs = inputs.Select(s => ToFixedWidths(s, ',', widths)).ToList();

        outputs.ForEach(s => System.Diagnostics.Debug.WriteLine(s));

        Console.ReadLine();
    }

    private static string ToFixedWidths(string s, char separator, List<int> widths)
    {
        List<string> split = s.Split(separator).ToList();

        // TODO: Error handling - what if there are more/less separators in
        // string s than we have width values?

        return string.Join(String.Empty, split.Select((ss, i) => ss.PadRight(widths[i], ' ')).ToArray());
    }
}

不过,在生产场景中,我希望看到这些数据被读入适当的Person类,正如Matt在回答中所建议的那样。

lp0sw83n

lp0sw83n3#

据我所知,最简单的方法是使用PowerShell

PS >  Import-Csv .\x.csv | Format-Table -AutoSize

FirstName LastName  Title                    BirthDate  HireDate   City     Region
--------- --------  -----                    ---------  --------   ----     ------
Nancy     Davolio   Sales Representative     1948-12-08 1992-05-01 Seattle  WA
Andrew    Fuller    Vice President Sales     1952-02-19 1992-08-14 Tacoma   WA
Janet     Leverling Sales Representative     1963-08-30 1992-04-01 Kirkland WA
...
hjzp0vay

hjzp0vay4#

你有两个问题,分开考虑,你会更容易找到一个好的解决办法。
1.将CSV格式的输入数据解析为有用的格式。
1.以特定方式呈现数据
不要编写自己的CSV解析器。规则有点复杂,但格式是众所周知的。从长远来看,出错将是不好的。您可以调用.NET框架中现有的CSV库,但我对它们了解不多。然而,这个问题非常适合C#中新的dynamic特性。下面是一个看起来很有前途的解析器:http://tonikielo.blogspot.com/2010/01/c-40-dynamic-linq-to-csvhe.html
我假设打印数据是一个小问题,您不需要我们的帮助。如果不需要,您需要给予我们一些更多的信息,比如您希望如何决定列宽。

mnemlml8

mnemlml85#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace StringParsingWithLinq
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var inputs = new List<string>
                             {
                                 "FirstName,LastName,Title,BirthDate,HireDate,City,Region",
                                 "Nancy,Davolio,Sales Representative,1948-12-08,1992-05-01,Seattle,WA",
                                 "Andrew,Fuller,\"Vice President, Sales\",1952-02-19,1992-08-14,Tacoma,WA",
                                 "Janet,Leverling,Sales Representative,1963-08-30,1992-04-01,Kirkland,WA",
                                 "Margaret,Peacock,Sales Representative,1937-09-19,1993-05-03,Redmond,WA",
                                 "Steven,Buchanan,Sales Manager,1955-03-04,1993-10-17,London,NULL",
                                 "Michael,Suyama,Sales Representative,1963-07-02,1993-10-17,London,NULL",
                                 "Robert,King,Sales Representative,1960-05-29,1994-01-02,London,NULL",
                                 "Laura,Callahan,Inside Sales Coordinator,1958-01-09,1994-03-05,Seattle,WA",
                                 "Anne,Dodsworth,Sales Representative,1966-01-27,1994-11-15,London,NULL"
                             };

            Console.Write(FixedWidthHelper.ReadLines(inputs)
                              .ToFixedLengthString());
            Console.ReadLine();
        }

        #region Nested type: FixedWidthHelper

        public class FixedWidthHelper
        {
            private readonly Regex _csvRegex = new Regex(",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))");
            private readonly List<string[]> _data = new List<string[]>();
            private List<int> _fieldLen;

            public static FixedWidthHelper ReadLines(List<string> lines)
            {
                var fw = new FixedWidthHelper();
                lines.ForEach(fw.AddDelimitedLine);
                return fw;
            }

            private void AddDelimitedLine(string line)
            {
                string[] fields = _csvRegex.Split(line);

                if (_fieldLen == null)
                    _fieldLen = new List<int>(fields.Select(f => f.Length));

                for (int i = 0; i < fields.Length; i++)
                {
                    if (fields[i].Length > _fieldLen[i])
                        _fieldLen[i] = fields[i].Length;
                }

                _data.Add(fields);
            }

            public string ToFixedLengthString()
            {
                var sb = new StringBuilder();
                foreach (var list in _data)
                {
                    for (int i = 0; i < list.Length; i++)
                    {
                        sb.Append(list[i].PadRight(_fieldLen[i] + 1, ' '));
                    }
                    sb.AppendLine();
                }

                return sb.ToString();
            }
        }

        #endregion
    }
}

jbose2ul

jbose2ul6#

我编写tablign就是为了这个目的。

pip install tablign

以及

tablign input.dat

我会给予你

FirstName , LastName  , Title                    , BirthDate  , HireDate   , City     , Region
Nancy     , Davolio   , Sales Representative     , 1948-12-08 , 1992-05-01 , Seattle  , WA
Andrew    , Fuller    , Vice President Sales     , 1952-02-19 , 1992-08-14 , Tacoma   , WA
Janet     , Leverling , Sales Representative     , 1963-08-30 , 1992-04-01 , Kirkland , WA
Margaret  , Peacock   , Sales Representative     , 1937-09-19 , 1993-05-03 , Redmond  , WA
Steven    , Buchanan  , Sales Manager            , 1955-03-04 , 1993-10-17 , London   , NULL
Michael   , Suyama    , Sales Representative     , 1963-07-02 , 1993-10-17 , London   , NULL
Robert    , King      , Sales Representative     , 1960-05-29 , 1994-01-02 , London   , NULL
Laura     , Callahan  , Inside Sales Coordinator , 1958-01-09 , 1994-03-05 , Seattle  , WA
Anne      , Dodsworth , Sales Representative     , 1966-01-27 , 1994-11-15 , London   , NULL

从那里,应该很容易使文件适应您的需要。

相关问题