“Datatable根据字符拆分列值在C#中”

huangapple go评论76阅读模式
英文:

Datatable split column value based on character in c#

问题

I want to split the column of a datatable like below:

Message

PR-111: test message
PR-112 - test message new
PR-113 : test message new2

It should split into a datatable like below:

PRNumber Message


PR-111 test message
PR-112 test message new
PR-113 test message new2

Note: There may be space before after the : or -

I have tried below but not giving proper result:

var r = dt1.AsEnumerable().Select(g => new {
           
            PRNumber = g["Message"].ToString().Contains(":") == true ? g["Message"].ToString().Split(':')[0] : g["Message"].ToString().Split('-')[0],
            Message = g["Message"].ToString().Contains(":") == true ? g["Message"].ToString().Split(':')[0] : g["Message"].ToString().Split('-')[1]
        }).ToList();

Can someone help on this please?

英文:

I want to split the column of a datatable like below

Message
--------
PR-111: test message
PR-112 - test message new
PR-113 : test message new2

It should split into a datatable like below

PRNumber    Message
------  -----------
PR-111  test message
PR-112  test message new
PR-113  test message new2

Note: There may be space before after the : or -

I have tried below but not giving proper result

 var r = dt1.AsEnumerable().Select(g => new {
           
            PRNumber = g["Message"].ToString().Contains(":") == true ? g["Message"].ToString().Split(':')[0] : g["Message"].ToString().Split('-')[0],
            Message = g["Message"].ToString().Contains(":") == true ? g["Message"].ToString().Split(':')[0] : g["Message"].ToString().Split('-')[1]
        }).ToList();

Can someone help on this please?

答案1

得分: 1

DataTable dt2 = new DataTable();
dt2.Columns.Add("PRNumber");
dt2.Columns.Add("Message");

foreach(DataRow row in dt1.Rows)
{
    string message = row.Field<string>("Message");
    string[] cols = message.Split(new[]{" : ", " - "}, StringSplitOptions.None);
    dt2.Rows.Add(cols.First().Trim(), cols.Last().Trim());
}

DataTable dt1 = new DataTable();
dt1.Columns.Add("Message");
dt1.Rows.Add("PR-111: test message");
dt1.Rows.Add("PR-112 : test message");
dt1.Rows.Add("PR-113 - test message new");
dt1.Rows.Add("PR-114 : test message new2");
dt1.Rows.Add("PR - 115 : test message new3");

(string Number, string Message) ParseMessage(string message)
{
    if(!message.StartsWith("PR", StringComparison.OrdinalIgnoreCase))
    {    
        return (null, message);
    }

    var prPart = message.TakeWhile(c => !char.IsDigit(c));
    var prNumberPart = message.Skip(prPart.Count()).TakeWhile(char.IsDigit);
    string prNumberString = string.Concat(prPart.Concat(prNumberPart));
    string prNumber = prNumberString.Replace(" ", "");
    string messagePart = message.Substring(prNumberString.Length).Trim(' ', '-', ':');
    
    return (prNumber, messagePart);
}

foreach(DataRow row in dt1.Rows)
{
    (string Number, string Message) = ParseMessage(row.Field<string>("Message"));
    dt2.Rows.Add(Number, Message);
}
英文:

Since you want to create a new DataTable with two columns, you should create it first:

DataTable dt2 = new DataTable();
dt2.Columns.Add(&quot;PRNumber&quot;);
dt2.Columns.Add(&quot;Message&quot;);

Now a simple foreach is the best way to fill it, LINQ doesn't help you:

foreach(DataRow row in dt1.Rows)
{
    string message = row.Field&lt;string&gt;(&quot;Message&quot;);
    // now use String.Split with two delimiter stings including the spaces
    string[] cols = message.Split(new[]{&quot; : &quot;, &quot; - &quot;}, StringSplitOptions.None);
	dt2.Rows.Add(cols.First().Trim(), cols.Last().Trim());
}

Since you have added now some edge cases like these:

DataTable dt1 = new DataTable();
dt1.Columns.Add(&quot;Message&quot;);
dt1.Rows.Add(&quot;PR-111: test message&quot;);
dt1.Rows.Add(&quot;PR-112 : test message&quot;);
dt1.Rows.Add(&quot;PR-113 - test message new&quot;);
dt1.Rows.Add(&quot;PR-114 : test message new2&quot;);
dt1.Rows.Add(&quot;PR - 115 : test message new3&quot;);

It doesn't make any sense to use string.Split anymore, you need a simple parser, for example:

(string Number, string Message) ParseMessage(string message)
{
	if(!message.StartsWith(&quot;PR&quot;, StringComparison.OrdinalIgnoreCase))
	{	
		return (null, message);
	}

	var prPart = message.TakeWhile(c =&gt; !char.IsDigit(c));;
	var prNumberPart = message.Skip(prPart.Count()).TakeWhile(char.IsDigit);
	string prNumberString = string.Concat(prPart.Concat(prNumberPart));
	string prNumber = prNumberString.Replace(&quot; &quot;, &quot;&quot;);
	string messagePart = message.Substring(prNumberString.Length).Trim(&#39; &#39;, &#39;-&#39;, &#39;:&#39;);
	
	return (prNumber, messagePart);
}

You can call the parse method in this way:

foreach(DataRow row in dt1.Rows)
{
    (string Number, string Message) = ParseMessage(row.Field&lt;string&gt;(&quot;Message&quot;));
	dt2.Rows.Add(Number, Message);
}

huangapple
  • 本文由 发表于 2023年5月7日 18:17:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76193303.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定