【问题标题】:How to check if a string contains a word and ignore special characters?如何检查字符串是否包含单词并忽略特殊字符?
【发布时间】:2021-10-08 13:59:55
【问题描述】:

我需要检查一个句子是否包含字符串数组中的任何单词,但在检查时应该忽略逗号等特殊字符。但结果应该有原句。

比如我有一句话"Tesla car price is $ 250,000." 在我的单词数组中我有wrdList = new string[5]{ "250000", "Apple", "40.00"};

我已经写了下面这行代码,但它没有返回结果,因为 250,000 和 250000 不匹配。

List<string> res = row.ItemArray.Where(itmArr => wrdList.Any(wrd => itmArr.ToString().ToLower().Contains(wrd.ToString()))).OfType<string>().ToList();

还有一件重要的事情是,如果它与字符串数组匹配,我需要得到原始句子。

例如,结果应该是"Tesla car price is $ 250,000." 不像"Tesla car price is $ 250000."

【问题讨论】:

  • 你不能简单地拆分字符串和TryParse它并检查数字吗?
  • .ToString().ToLower() -> .ToString().ToLower().Replace(",", "")?
  • 如果类型已经是string,我怀疑你是否需要所有这些ToStrings
  • 如果您的单词数组可以包含字符,那么您似乎也想在wrd 上执行ToLower()
  • 特殊字符不能是“任何”。这意味着任何字符都是特殊字符。你的意思是标点符号吗?

标签: c# .net linq


【解决方案1】:

Replace(",", "")怎么样

itmArr.ToString().ToLower().Replace(",", "").Contains(wrd.ToString())

附注:.ToLower() 不是必需的,因为数字不区分大小写,字符串不需要.ToString()

所以结果也可能是

itmArr.Replace(",", "").Contains(wrd)

https://dotnetfiddle.net/A2zN0d


更新 sice , 可能是不同的字符 - 基于文化,您也可以使用 ystem.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberGroupSeparator 而是

【讨论】:

  • 但这会因不同的文化而失败,例如使用 ' 而不是 , "250'000"
  • 问题是关于逗号的:它应该忽略特殊字符逗号。
  • @fubo - 抱歉,我错过了在我的问题中添加一点。我现在已经更新了问题。
  • @StefanoCavion 更新
【解决方案2】:

大多数文本匹配问题要考虑的第一个选项是使用正则表达式。这将解决您的问题。解决方案的核心部分是构造一个合适的正则表达式来匹配你需要匹配的内容。

您有一个单词列表,但我只关注一个单词。您的要求指定要匹配“单词”。因此,首先,您可以使用“单词边界”模式\b。要匹配单词“250000”,正则表达式将为\b250000\b

您的要求还指定单词可以“包含”“特殊”字符。为了使其正常工作,您需要清楚“包含”的含义以及哪些字符是“特殊的”。

对于“包含”要求,我假设您的意思是特殊字符可以位于单词中的任意两个字符之间,但不能位于第一个或最后一个字符之间。所以对于单词“250000”,这个字符串中的任何问号都可以是一个特殊字符:“2?5?0?0?0?0”。

对于“特殊”要求,有一些选项取决于您的要求。如果只是标点符号,可以使用字符类\p{P}。如果需要指定特殊字符的特定列表,可以使用字符组。例如,如果您唯一的特殊字符是逗号,则字符组将为 [,]

要将所有这些放在一起,您将创建一个函数来为每个目标单词构建适当的正则表达式,然后使用它来检查您的句子。像这样的:

public static void Main()
{
    string sentence = "Tesla car price is $ 250,000.";
    var targetWords = new string[]{ "250000", "350000", "400000"};
    Console.WriteLine($"Contains target word? {ContainsTarget(sentence, targetWords)}");
}

private static bool ContainsTarget(string sentence, string[] targetWords)
{
    return targetWords.Any(targetWord => ContainsTarget(sentence, targetWord));
}

private static bool ContainsTarget(string sentence, string targetWord)
{
    string targetWordExpression = TargetWordExpression(targetWord);
    var re = new Regex(targetWordExpression);
    return re.IsMatch(sentence);
}

private static string TargetWordExpression(string targetWord)
{
    var sb = new StringBuilder();
    // If special characters means a specific list, use this:
    string specialCharacterMatch = $"[,]?";
    // If special characters means any punctuation, then you can use this:
    //string specialCharactersMatch = "\\p{P}?";
    
    bool any = false;
    foreach (char c in targetWord)
    {
        if (any)
        {
            sb.Append(specialCharacterMatch);
        }
        any = true;
        sb.Append(c);
    }
    
    return $"\\b{sb}\\b";
}

工作代码:https://dotnetfiddle.net/5UJSur

【讨论】:

    【解决方案3】:

    希望以下解决方案能有所帮助,

    • 使用正则表达式去除非字母数字字符

    • 如果包含来自 wrdList 的任何匹配单词,则返回原始字符串。

       string s = "Tesla car price is $ 250,000.";
           string[] wrdList = new string[3] { "250000", "Apple", "40.00" };
      
           Regex rgx = new Regex("[^a-zA-Z0-9 -]");
           string str = rgx.Replace(s, "");
      
           if (wrdList.Any(str.Contains))
           {
               Console.Write(s);
           }
           else
           {
               Console.Write("No Match Found!");
           }
      

    在小提琴上上传以进行更多探索 https://dotnetfiddle.net/zbwuDy

    除了段落之外,还可以拆分成句子数组并遍历。在下面的小提琴上检查相同的内容。 https://dotnetfiddle.net/AvO6FJ

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 1970-01-01
    • 2010-12-20
    • 2016-08-24
    • 2011-05-20
    • 2013-12-23
    相关资源
    最近更新 更多