在一个数组中修剪所有的字符串

83

我有一个字符串,它的格式是:

string email = "a@a.com, b@b.com, c@c.com";

我想将它分割成一个字符串数组。

如果我这样做:

string[] emails = email.Split(',');
我在每个电子邮件地址前(除了第一个电子邮件地址之外)都会有空格:
emails[0] = "a@a.com"
emails[1] = " b@b.com"
emails[2] = " c@c.com"

如何最好地获取这个(无论是更好的解析方法还是将数组中的所有字符串修剪的方法)?

emails[0] = "a@a.com"
emails[1] = "b@b.com"
emails[2] = "c@c.com"

2
如果空格始终存在,您可以将其添加到拆分中...即:email.Split(','); - nilamo
12个回答

263
emails.Split(',').Select(email => email.Trim()).ToArray()

3
@Moismyname:我不确定什么限制会导致你走这条路,但有其他答案可以解决你的问题。 - Bryan Watts
10
这篇回答比被采纳的答案更好,因为问题是要对每个字符串进行修剪(TRIM),而不一定是用空格替换。 - daveD
如果某个元素为空怎么办? - sairfan
1
@IrfanUllah:链接一个 .Where(email => email != null) - Bryan Watts
1
@MinhTran 这确实是一个函数调用 - Select 是一组扩展方法,它们构成了位于 System.Linq 命名空间中的 LINQ。 - Bryan Watts
显示剩余6条评论

41

您还可以替换所有空格的出现,从而避免foreach循环:

string email = "a@a.com, b@b.com, c@c.com";    
string[] emails = email.Replace(" ", "").Split(',');

13
针对这个具体示例,它能够正常工作,但无法保留结果元素中的空格,比如:“foo bar,another element,blah_blah”。在我看来,Bryan Watts 的回答最好。 - revgum
1
嗨@revgum!那是真的,但我已经坚持遵守@leora的要求。你所描述的例子,在我看来,超出了这个问题的范围。无论如何,感谢您的反馈。 - nick2083
2
-1 我同意这不是一个好的做法。买家要谨慎。 - Scott Adams
也被踩了。我同意这个答案可以解决问题,但是Bryan的回答更加通用。 - Joris Van Regemortel
这不对。它不会修剪,而是从数组中的字符串中删除空格,这与修剪(删除尾随和前导空格)完全不同。 - SimpleGuy

23

以下两种方式都可以。我会建议使用第一种方式,因为它更准确地表达了连接字符串的含义。

string[] emails = email.Split(new string[] { ", " }, StringSplitOptions.None);
string[] emails = email.Split(new char[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries);

+1 我不知道有这些选项。从 Perl 转过来,我到处都看到正则表达式。使用 Split 选项是正确的方法。 - Brian Rasmussen
2
+1 我们使用LINQ如此频繁,以至于我们往往忘记了其他优雅的选项确实存在。 - Stan R.
在这种特定情况下,电子邮件地址不能有空格,因此我会使用第二个选项。 - Moses

11
您可以使用 Trim():
string email = "a@a.com, b@b.com, c@c.com";
string[] emails = email.Split(',');
emails = (from e in emails
          select e.Trim()).ToArray();

这个答案是正确的,但有点过度,这个答案是最好的方法:https://dev59.com/z3M_5IYBdhLWcg3wfTO7#1355732 - Andrew Hare

8
使用 Regex.Split 避免修剪。
var emails = Regex.Split(email, @",\s*");

6

.NET 5已经面世了,它带来了一个现代的解决方案:

string[] emails = email.Split(',', StringSplitOptions.TrimEntries);

这应该被视为最佳选项,因为它比这里的任何其他答案都更完美。 - cdie

5
您可以使用以下一行代码解决此问题:
string[] emails = text.Split(',', StringSplitOptions.RemoveEmptyEntries);
Array.ForEach<string>(emails, x => emails[Array.IndexOf<string>(emails, x)] = x.Trim());

4
如果你只需要操作条目,而不需要返回数组:
string[] emails = text.Split(',');
Array.ForEach(emails, e => e.Trim());

2

或者,您可以使用形式为的正则表达式进行拆分:

\s*,\s*

即。
string[] emails = Regex.Split(email, @"\s*,\s*");

它将直接消耗周围的空格。

正则表达式通常会影响性能,但你提供的示例表明这是你计划在代码中为一个短数组执行一次的操作。


1
布莱恩·沃茨的答案优雅而简单。他隐含地引用了Split()创建的字符串数组。
如果您正在读取文件并希望在构建数组时对数据进行处理,请注意其可扩展性。
string sFileA = @"C:\Documents and Settings\FileA.txt";
string sFileB = @"C:\Documents and Settings\FileB.txt";

// Trim extraneous spaces from the first file's data
string[] fileAData = (from line in File.ReadAllLines( sFileA )
                      select line.Trim()).ToArray();

// Strip a second unneeded column from the second file's data
string[] fileBData = (from line in File.ReadAllLines( sFileB )
                      select line.Substring( 0, 21 ).Trim()).ToArray();

当然,如果您喜欢,也可以使用Linq =>符号。
string[] fileBData = File.ReadAllLines( sFileB ).Select( line =>
                             line.Substring( 0, 21 ).Trim()).ToArray();

尽管我的答案应该作为评论发布,但我还没有足够的声望点来发表评论。但是我发现这次讨论对我在使用ReadAllLines()时如何处理数据非常有价值。

欢迎来到[SO]。关于您的代码,有一个小建议:如果您使用Linq,最好使用File.ReadLinesReadAllLines会将整个文件读入内存数组中,对于大文件可能会出现问题。而ReadLines每次只读取一行,如果您不需要保留初始版本的内容,这是非常好的选择。 - RoadieRich
谢谢!我可以看到使用ReadAllLines的示例对于非常大的文件会出现问题,因为原始数据和修剪版本同时在内存中,这只是暂时的。File.ReadLines()的文档页面也有一个符合这个讨论的示例。 - RonSanderson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接