C# 从字符串列表中删除子字符串

C# 从字符串列表中删除子字符串,c#,regex,linq,list,replace,C#,Regex,Linq,List,Replace,我有一个包含禁用单词的字符串列表。检查字符串是否包含任何被禁止的单词并将其从字符串中删除的有效方法是什么?目前,我有以下几点: cleaned = String.Join(" ", str.Split().Where(b => !bannedWords.Contains(b, StringComparer.OrdinalIgnoreCase)).ToArray()); 这适用于单个禁用单词,但不适用于短语(例如,多个单词)。任何超过

我有一个包含禁用单词的字符串列表。检查字符串是否包含任何被禁止的单词并将其从字符串中删除的有效方法是什么?目前,我有以下几点:

cleaned = String.Join(" ", str.Split().Where(b => !bannedWords.Contains(b,
                            StringComparer.OrdinalIgnoreCase)).ToArray());

这适用于单个禁用单词,但不适用于短语(例如,
多个单词
)。任何超过一个单词的
实例也应删除。我想尝试的另一种方法是使用List的Contains方法,但它只返回bool,而不返回匹配单词的索引。如果我能得到匹配单词的索引,我就可以使用
String.Replace(bannedWords[I],“”)

它不起作用,因为您有冲突的定义


当你想寻找像
多个单词这样的子句时,你不能再在空白处拆分了。您将不得不求助于
String.IndexOf()

它不起作用,因为您有冲突的定义


当你想寻找像
多个单词这样的子句时,你不能再在空白处拆分了。您将不得不求助于
String.IndexOf()

如果您追求的是性能,我想您不会担心一次性的设置时间,而是担心连续的性能。因此,我将构建一个包含所有禁用表达式的大型正则表达式,并确保它已编译-这是一个设置

然后我会尝试将它与文本匹配,并将每个匹配项替换为一个空格或任何你想替换的内容


这样做的原因是,一个大型正则表达式应该编译成类似于手动创建的有限状态自动机的东西来处理这个问题,所以它应该运行得很好。

如果您追求的是性能,我假设您不担心一次性设置时间,而是担心连续性能。因此,我将构建一个包含所有禁用表达式的大型正则表达式,并确保它已编译-这是一个设置

然后我会尝试将它与文本匹配,并将每个匹配项替换为一个空格或任何你想替换的内容


这样做的原因是,一个大的正则表达式应该编译成类似于手动创建的有限状态自动机的东西来处理这个问题,所以它应该运行得很好。

一个简单的
字符串。Replace
将不起作用,因为它将删除单词部分。如果“sex”是一个被禁止的词,而你有“sextet”这个词,这是不被禁止的,你应该保持原样

使用
Regex
您可以在带有

string text = "A sextet is a musical composition for six instruments or voices.".
string word = "sex";
var matches = Regex.Matches(text, @"(?<=\b)" + word + @"(?=\b)");
注意:我使用了以下
Regex
模式

(?<=prefix)find(?=suffix)
然后重复地将其应用到不同的文本中

string result = regex.Replace(text, "");

简单的
字符串.Replace将不起作用,因为它将删除单词部分。如果“sex”是一个被禁止的词,而你有“sextet”这个词,这是不被禁止的,你应该保持原样

使用
Regex
您可以在带有

string text = "A sextet is a musical composition for six instruments or voices.".
string word = "sex";
var matches = Regex.Matches(text, @"(?<=\b)" + word + @"(?=\b)");
注意:我使用了以下
Regex
模式

(?<=prefix)find(?=suffix)
然后重复地将其应用到不同的文本中

string result = regex.Replace(text, "");

为什么不遍历禁用词列表,并使用
string.IndexOf
方法在字符串中查找每个禁用词呢。 例如,您可以使用以下代码删除禁用的单词和短语:

myForbWords.ForEach(delegate(string item) {
    int occ = str.IndexOf(item);
    if(occ > -1) str = str.Remove(occ, item.Length);
});

myForbWords的类型是
List

为什么不使用
string.IndexOf
方法遍历禁用单词的列表并在字符串中查找每个单词呢。 例如,您可以使用以下代码删除禁用的单词和短语:

myForbWords.ForEach(delegate(string item) {
    int occ = str.IndexOf(item);
    if(occ > -1) str = str.Remove(occ, item.Length);
});

MyForbWord的类型是
列表

以何种方式有效?演出代码长度?问题归结为一个简单的查找和替换,直到你犯了一个错误:你的解决方案在“多个单词”方面有什么问题?如果重叠,你可以按长度排序,从大到小?更有效的方法是“枚举”整个过程,但您仍然必须小心“重叠”。以何种方式有效?演出代码长度?问题归结为一个简单的查找和替换,直到你犯了一个错误:你的解决方案在“多个单词”方面有什么问题?如果重叠,你可以按长度排序,从大到小?更有效的方法是通过“枚举”来完成,但你仍然必须小心“重叠”。谢谢,我认为这是最好的方法,但我注意到整个单词没有匹配。我有
xyzs
,我搜索
xyz
(不应该找到匹配项,因为它是
xyzs
),但是找到了匹配项,它删除了
xyz
,但保留了
s
。可能是我的错误,但它应该匹配整个短语。你注意到我在
@(“谢谢,我认为这是最好的方法,但我注意到整个单词没有匹配。我有
x y zs
,我搜索
x y z
(因为它是
x y zs
),所以不应该找到匹配项),但找到了匹配项,它删除了
x y z
,但保留了
s
。这可能是我的错误,但它应该匹配整个短语。您注意到我在
@中添加了括号了吗(?这似乎匹配部分单词而不是整个单词。因此,如果我尝试替换
turn
,它会将
turn
更改为
ing
,但它不应该影响
turn
,因为这不是我想要替换的单词。没错。我错过了。正如您指出的,这可能会发生。因此检查以下字符occ(出现)之后的字符,无论是字母数字字符还是数字字符,都可以解决此问题。这似乎与部分单词匹配,而不是与整个单词匹配。因此,如果我尝试替换
turn
,它会将
turn
更改为
ing
,但不会影响