在.NET中检查逗号分隔列表中的字符串的最佳方法是什么?

28

我正在从配置文件读取逗号分隔的字符串列表。我需要检查另一个字符串是否在该列表中。例如:

"苹果,香蕉,奶酪"

如果我检查"苹果",我应该能够找到它,但如果我检查"app",我不应该找到。

最简单明了的方法是什么?速度并不重要。

(我会将我的解决方案添加为答案,但我希望有更好的方法。)

9个回答

51
使用 LINQ:
listString.Split(',').Contains("apple")

不使用 LINQ:

Array.IndexOf(listString.Split(','), "apple") >= 0

1
我不明白。String.Split返回一个数组。数组没有Contains方法。 - Jeremy Stein
2
你必须使用.NET3.5+,并且在某个地方使用了'using System.Linq'。 - nothrow
1
有一个 Contains LINQ 扩展方法可以用于数组。但如果你使用的是 .Net 1.1 或 2.0,则无法使用该方法。 - Ryan Alford
2
这不仅速度不慢,而且立即明确正在发生的事情。您无法对正则表达式解决方案说出同样的话。 - Lucas Jones
哦,我明白了。我的项目是针对.NET 2.0的。我得检查一下目标机器支持什么。 - Jeremy Stein
4
如果您无法访问Linq,仍然可以使用:Array.IndexOf(listString.Split(','), "apple") >= 0 - Fábio Batista

13
(","+listString+",").Contains(","+testWord+",");

但并不是直接的。


1
我过去常常使用这种方法。它的优点是不会创建N个新字符串。 - harpo
3
如果您的逗号分隔字符串很长,使用此方法比拆分更节省空间。 - Dirk Vollmar
1
对于.NET 2.0,我认为这可能是最好的解决方案。很容易看出为什么要添加逗号,而且只需要一个方法调用。我喜欢它。 - Jeremy Stein

8

正则表达式可能不算“直截了当”,但这是我得到的:

Regex.IsMatch(listString, "(?<=,|^)" + testWord + "(?=,|$)")

更新: 根据Eric在下面的评论中提到的,应该是这样的:

Regex.IsMatch(listString, "(?<=,|^)" + Regex.Escape(testWord) + "(?=,|$)")

4
当然,如果“testWord”包含任何在正则表达式中具有意义的符号,那么你就会遇到大问题。 - Eric Lippert
1
哇,我没有想到那个。好观点!我想我很容易受到正则表达式注入攻击! :) - Jeremy Stein
你是什么意思?正则表达式很棒! - Damian Powell

3

感谢您包含非Linq版本。可惜它太啰嗦了。 - Jeremy Stein
3
由于Array实现了IList<T>接口,你不需要创建第二个List<string>。以下的代码变体可以在.NET 2.0中使用:((IList<string>)listString.Split(',')).Contains(...)。 - Joe

2

这个方法可行,但如果正则表达式变得复杂,它会变得非常慢。话虽如此,单词边界锚点使这种操作变得相当容易。

var foods = "apple,banana,cheese";

var match = Regex.Match(foods, @"\bapple\b");

if (match.Success)
    Console.WriteLine(match.Value);

1
哦,这让我的复杂的前瞻解决方案显得愚蠢了。谢谢。 - Jeremy Stein

1

这里有一个忽略大小写的选项。

var food = "apple,banana,cheese";

bool containsApp = food.Split(',')
                       .Where(s => string.Compare("app", s, true) == 0)
                       .Count() > 0;

bool containsApple = food.Split(',')
                         .Where(s => string.Compare("apple", s, true) == 0)
                         .Count() > 0;

Console.WriteLine("Contains \"app\"? {0}", containsApp);
Console.WriteLine("Contains \"apple\"? {0}", containsApple);

如果您正在使用linq,那么IEnumerable<T>.Compare有一个重载,它接受一个IEqualityComparer<T> - Lee
+1 为文化敏感的字符串比较!“Caf\u00E9”和“Cafe\u0301”看起来相同,它们应该被视为相等! - Jeffrey L Whitledge

1

答案取决于逗号分隔列表的语法规则。

如果规则要求列表与您发布的完全相同(没有空格,没有尾随逗号),那么任务可以分解为其组成部分:

字符串是否以apple,开头?(String.StartsWith)
字符串是否以,apple结尾?(String.EndsWith)
字符串是否包含,apple,?(String.Contains)

如果规则更加复杂,则正则表达式方法成为唯一的方式,而不必完全处理列表或编写大量规则。

如果您正在针对同一字符串检查多个项目,则应将字符串转换为缓存的列表,然后进行检查。 String.Split方法将为您执行此操作。


0
                 public bool GetIsExistSubstring(string mainstring, string substring)
    {        
        bool Isexist=false;
        int i = -1;
        mainstring = string.Format(",{0},", mainstring);//so it will be like  ,1,2,3,
        substring = string.Format(",{0},", substring);//so it will be like  ,1,
        i=mainstring.IndexOf(substring);

        if(i!=-1)
        {
            Isexist = true;
        }
        return Isexist;
    }

请尝试回答新的问题。这个问题是在2010年被提出并得到了回答。 - Umair Farooq

0

这是忽略大小写和文化的解决方案(或选择StringComparer属性之一)

var commaDelimitedString = "string1,string2,string3,string4";
var testString = string2.trim; // trim to remove the spaces coz you may be getting it from UI
if(commaDelimitedString.split(',').contains(testString,StringComparer.InvariantCultureIgnoreCase))
{
     //TODO: What to do when condition is true
}
else
{
     //TODO: What to do when condition is false
}

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