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

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

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:

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

Can someone help on this please?

英文:

I want to split the column of a datatable like below

  1. Message
  2. --------
  3. PR-111: test message
  4. PR-112 - test message new
  5. PR-113 : test message new2

It should split into a datatable like below

  1. PRNumber Message
  2. ------ -----------
  3. PR-111 test message
  4. PR-112 test message new
  5. PR-113 test message new2

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

I have tried below but not giving proper result

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

Can someone help on this please?

答案1

得分: 1

  1. DataTable dt2 = new DataTable();
  2. dt2.Columns.Add("PRNumber");
  3. dt2.Columns.Add("Message");
  4. foreach(DataRow row in dt1.Rows)
  5. {
  6. string message = row.Field<string>("Message");
  7. string[] cols = message.Split(new[]{" : ", " - "}, StringSplitOptions.None);
  8. dt2.Rows.Add(cols.First().Trim(), cols.Last().Trim());
  9. }
  10. DataTable dt1 = new DataTable();
  11. dt1.Columns.Add("Message");
  12. dt1.Rows.Add("PR-111: test message");
  13. dt1.Rows.Add("PR-112 : test message");
  14. dt1.Rows.Add("PR-113 - test message new");
  15. dt1.Rows.Add("PR-114 : test message new2");
  16. dt1.Rows.Add("PR - 115 : test message new3");
  17. (string Number, string Message) ParseMessage(string message)
  18. {
  19. if(!message.StartsWith("PR", StringComparison.OrdinalIgnoreCase))
  20. {
  21. return (null, message);
  22. }
  23. var prPart = message.TakeWhile(c => !char.IsDigit(c));
  24. var prNumberPart = message.Skip(prPart.Count()).TakeWhile(char.IsDigit);
  25. string prNumberString = string.Concat(prPart.Concat(prNumberPart));
  26. string prNumber = prNumberString.Replace(" ", "");
  27. string messagePart = message.Substring(prNumberString.Length).Trim(' ', '-', ':');
  28. return (prNumber, messagePart);
  29. }
  30. foreach(DataRow row in dt1.Rows)
  31. {
  32. (string Number, string Message) = ParseMessage(row.Field<string>("Message"));
  33. dt2.Rows.Add(Number, Message);
  34. }
英文:

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

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

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

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

Since you have added now some edge cases like these:

  1. DataTable dt1 = new DataTable();
  2. dt1.Columns.Add(&quot;Message&quot;);
  3. dt1.Rows.Add(&quot;PR-111: test message&quot;);
  4. dt1.Rows.Add(&quot;PR-112 : test message&quot;);
  5. dt1.Rows.Add(&quot;PR-113 - test message new&quot;);
  6. dt1.Rows.Add(&quot;PR-114 : test message new2&quot;);
  7. 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:

  1. (string Number, string Message) ParseMessage(string message)
  2. {
  3. if(!message.StartsWith(&quot;PR&quot;, StringComparison.OrdinalIgnoreCase))
  4. {
  5. return (null, message);
  6. }
  7. var prPart = message.TakeWhile(c =&gt; !char.IsDigit(c));;
  8. var prNumberPart = message.Skip(prPart.Count()).TakeWhile(char.IsDigit);
  9. string prNumberString = string.Concat(prPart.Concat(prNumberPart));
  10. string prNumber = prNumberString.Replace(&quot; &quot;, &quot;&quot;);
  11. string messagePart = message.Substring(prNumberString.Length).Trim(&#39; &#39;, &#39;-&#39;, &#39;:&#39;);
  12. return (prNumber, messagePart);
  13. }

You can call the parse method in this way:

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

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:

确定