【问题标题】:check if word contains substring from list of strings检查单词是否包含字符串列表中的子字符串
【发布时间】:2015-02-17 16:18:47
【问题描述】:

我已经看到使用 linq 执行此操作的示例,如下所示:

List<string> list = new List<string> {"One", "Two", "Three", "Four", "five", "six" };
string text = "OneTwoThreeFour";

list.Any(s => text.contains(s))

但这适用于所有可能的词吗?意思是,如果我有一个由 3 个较小的词组成的大词(不被任何特殊字符分隔),它会捕获所有 3 个子词吗?还是会在找到一个匹配项后停止检查?

我想要完成的是取一个像"OneTwoThreeFour" 这样的词,并在每个唯一词之间添加一个空格或破折号,这样它就是"One Two Three Four"

有没有更好的方法来做到这一点?

是否可以获得作为匹配返回的“字符串”?

【问题讨论】:

  • 您能否举例说明列表中包含的内容以及您的text
  • 请稍等
  • 预期输出是什么?
  • 问题已经出现了,我想把OneTwoThreeFour变成One Two Three Four
  • 您有运行时可用的“所有可能的单词”字典吗?单词是否用大写字母表示?你有区分“room”、“plan”和“roomplan”等复合词的计划吗?

标签: c# regex linq


【解决方案1】:

更新以涵盖任一情况:

您可以通过adding spaces before capital letters 获取来自text 的单词列表并在空间上进行拆分。然后您可以使用SequenceEqual() 将该结果与list 进行比较。

这是一个例子:

static void Main(string[] args)
{
    List<string> list = new List<string> {"One", "Two", "Three", "Four", "Five" };
    string text = "OneTwoThreeFourFive";

    string withSpaces = AddSpacesToSentence(text, true);
    List<string> list2 = withSpaces.Split(' ').ToList();

    bool b = list.SequenceEqual(list2);
}

// Refer to: https://stackoverflow.com/a/272929/4551527
static string AddSpacesToSentence(string text, bool preserveAcronyms)
{
    if (string.IsNullOrWhiteSpace(text))
        return string.Empty;
    StringBuilder newText = new StringBuilder(text.Length * 2);
    newText.Append(text[0]);
    for (int i = 1; i < text.Length; i++)
    {
        if (char.IsUpper(text[i]))
            if ((text[i - 1] != ' ' && !char.IsUpper(text[i - 1])) ||
                (preserveAcronyms && char.IsUpper(text[i - 1]) &&
                    i < text.Length - 1 && !char.IsUpper(text[i + 1])))
                newText.Append(' ');
        newText.Append(text[i]);
    }
    return newText.ToString();
}

请注意,我从这个答案中获得了 AddSpacesToSentence 的实现:https://stackoverflow.com/a/272929/4551527

另一个更新

顺便说一句,如果列表中单词的顺序不重要(换句话说:“OneTwo”应该匹配{“Two”,“One”}),那么你可以在做之前Sort()两个列表SequenceEquals()


原创(当我认为这是单向比较时)

您可以改用All()

List<string> list = new List<string> {"One", "Two", "Three", "Four" };
string text = "OneTwoThreeFour";

list.All(s => text.Contains(s))

如果序列中的所有元素都满足谓词(这里是包含),这将返回 true。

上面的sn-p返回true。如果将“五”添加到 list(但保持 text 相同),那么它将返回 false。

【讨论】:

  • 您的代码显示“任何”,如果文本只有列表中的 2 个单词怎么办?
【解决方案2】:

一种简单的方法是遍历项目列表并执行String Replace (我使用过StringBuilder,您也可以使用String.Replace 比如:

List<string> list = new List<string> { "One", "Two", "Three", "Four", "five", "six" };
string text = "OneTwoThreeFour";
StringBuilder sb = new StringBuilder(text);
foreach (var str in list)
{
    sb.Replace(str, " " + str + " ");
}

string modifiedText = sb.ToString();

这会给你modifiedText = " One Two Three Four "。作为旁注,您不必检查列表中是否存在Any 项目。如果该项目在列表中不存在,String.Replace 将不会执行任何操作。

为:

它会捕获所有 3 个子词吗?或者一旦它停止检查 找到一个匹配项?

一旦找到匹配项,它将停止。您正在使用Enumerable.Any,一旦找到匹配项,将不再进行比较。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-25
    • 1970-01-01
    • 2011-11-09
    • 2013-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多