【问题标题】:How to compare a List and string and find the matching words in the string using c#?如何使用c#比较列表和字符串并在字符串中找到匹配的单词?
【发布时间】:2017-08-23 08:50:44
【问题描述】:

列表和字符串是:

string Text;
List<string> Names = new List<string>();

现在将数据从数据库加载到列表中:

string connectionString = "Data Source=SANGEEN-PC;Initial Catalog=IS_Project;Integrated Security=True;Connection Timeout=0";

using (SqlConnection cnn = new SqlConnection(connectionString))
{
     try
     {
         SqlDataAdapter da = new SqlDataAdapter("select NamesValues from Names", cnn);
         DataSet ds = new DataSet();
         da.Fill(ds, "Names");

         foreach (DataRow row in ds.Tables["Names"].Rows)
         {
             Names.Add(row["NamesValues"].ToString());
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show("Can not open connection ! ");
     }
 }

现在将数据加载到字符串:

Text = System.IO.File.ReadAllText(@"D:\Data-Sanitization-Project\Files\Test.txt");

现在我想比较名称和文本,这样:

  1. 查找同样在字符串(匹配的单词)中的所有列表项并将其存储在列表或数组中。
  2. 将所有找到的匹配词替换为“姓名”。
  3. 计算匹配的单词。

例子:

Names:                  Text:                                

Sangeen Khan           I am Sangeen Khan and i am friend    
Jhon                   Jhon. Jhon is friend of Wasim.                               
Wasim
Alexander
Afridi

所需操作:

Matched List/Array:    Matches:         Updated Text:         

 Sangeen Khan            4            I am "Name" and i am friend                 
 Jhon                                "Name". "Name" is friend of "Names".
 Wasim

针对以上三点,我写了如下代码,但是还是不行:

var TextRead = File.ReadAllLines(text);
HashSet<string> hashSet = new HashSet<string>(TextRead);

foreach (string i in Names)
{
   if (hashSet.Contains(i))
   {
       MessageBox.Show("found");
   }
}

我已尽力解释我的问题,但是,如果您了解我需要编辑,请随时编辑我的问题。先感谢您。

【问题讨论】:

  • 为什么你之前有 List 时还使用 hashset?你试过 Names.Contains() 吗?
  • @David Lindon 文本是字符串,我正试图在该字符串文本中查找单词。我不认为 .Contains() 可以与字符串一起使用
  • 对于计数,您要计算所有子字符串还是只计算匹配的单词?你定义中的一个词是什么?是空格分隔还是标点符号分隔,哪个字符?
  • 您注意到您的文本只包含一次Jhon,因为另一个是Jhnon

标签: c# string list


【解决方案1】:
  1. 查找同样在字符串(匹配的单词)中的所有列表项并将其存储在列表或数组中。
  2. 将所有找到的匹配词替换为“姓名”。
  3. 计算匹配的单词。

  1. List&lt;string&gt; matchedWords = Names.Where(Text.Contains).ToList();
  2. matchedWords.ForEach(w =&gt; Text = Text.Replace(w, "Names"));
  3. int numMatchedWords = matchedWords.Count;

似乎numMatchedWords 应该计算文本中的所有匹配项,所以甚至重复。然后您可以使用以下方法(在Replace 之前):

此扩展查找文本中所有单词的出现次数:

public static Dictionary<string, int> OccurencesInText(this IEnumerable<string> words, string text, StringComparison comparison = StringComparison.OrdinalIgnoreCase)
{
    if (text == null) throw new ArgumentNullException(nameof(text));

    Dictionary<string, int> resultDict = new Dictionary<string, int>();
    foreach (string word in words.Distinct())
    {
        int wordOccurrences = 0;
        for(int i = 0; i < text.Length - word.Length; i++)
        {
            string substring = text.Substring(i, word.Length);
            if (substring.Equals(word, comparison)) wordOccurrences++;
        }
        resultDict.Add(word, wordOccurrences);
    }
    return resultDict;
}

用法:

int numMatchedWords = matchedWords.OccurencesInText(Text).Sum(kv => kv.Value);

【讨论】:

  • 我不认为这正是 OP 想要的。看他的例子,匹配数应该是 4(重复“Jhon”)使用你的代码,匹配数应该是 3...
  • 嗯..只是在检查。我认为您还有另一个问题,要计算将文本拆分为单词的匹配项,但某些名称(Sangeen Khan)实际上是两个单词。这就是为什么在我的回答中我首先替换名称然后计数:)
  • 哦,是的,但是 OP 在示例中说他希望有 4 场比赛,所以我认为这是一个错字(我猜也不是 Jhon OP 是指 John ;)
  • 它给了我错误:错误 CS1061 'List' 不包含'OccurencesInText' 的定义,并且没有扩展方法'OccurencesInText' 接受'List' 类型的第一个参数可以找到(您是否缺少 using 指令或程序集引用?)比较术语 C:\Users\sange\Documents\Visual Studio 2015\Projects\Comparing terms\Comparing terms\Form1.cs 103 Active
  • @Tim Schmelter ,如果我从数据库加载列表,它将无法正常工作
【解决方案2】:
static void Main()
    {
        var count = 0;

        string text = "I am Sangeen Khan and i am friend Jhon. Jhnon is friend of Wasim.     ";
        List<string> Names = new List<string>() {"Sangeen Khan ", "Jhon","Wasim","Alexander","Afridi" };
        List<string> matchedList = new List<string>();

        foreach (var name in Names)
        {
            if(text.Contains(name))
            {
                text = text.Replace(name, "\"Name\" ");
                matchedList.Add(name);
                count++;
            }
        }

        foreach (var name in matchedList)
        {                
             Console.WriteLine(name);
        }

        Console.WriteLine(count);
        Console.WriteLine(text);

        Console.ReadLine();
    }

【讨论】:

    【解决方案3】:

    您可以循环运行您的名称并使用正则表达式搜索名称, 是 Match.Count > 0 那么你可以替换文本并计算你的 全局匹配计数。

    是 Match.Count == 0。 然后您可以在第二个列表中添加此名称...然后您可以在 for Each 循环之后从列表中删除名称。

            public static List<string> Names = new List<string>();
        public static string Text = "I am Sangeen Khan and i am friend Jhon. Jhon is friend of Wasim.";
        static void Main(string[] args)
        {
            Names.Add("Sangeen Khan");
            Names.Add("Jhon");
            Names.Add("Wasim");
            Names.Add("Alexander");
            Names.Add("Afridi");
    
            var matchCount = 0;
            var nameToRemove = new List<string>();
            foreach (var name in Names)
            {
                var regex = new Regex(name);
                var match = regex.Matches(Text);
    
                //Count of matches
                matchCount += match.Count;
    
                if (match.Count > 0)
                {
                    Text = regex.Replace(Text, "\"Name\"");
                }
                else
                {
                    nameToRemove.Add(name);
                }
            }
            nameToRemove.ForEach(name=> Names.Remove(name));
            Console.WriteLine($"Names: {string.Join(" ", Names)}");
            Console.WriteLine($"Count: {matchCount}");
            Console.WriteLine($"ReplaceText: {Text}");
            Console.ReadLine();
        }
    

    输出

    姓名:Sangeen Khan Jhon Wasim

    计数:4

    ReplaceText:我是“姓名”,我是朋友“姓名”。 “姓名”是“姓名”的朋友。

    【讨论】:

      【解决方案4】:

      由于您想用“姓名”替换列表中的姓名,我会先这样做,然后计算文本中出现的“姓名”。比如:

      string[] names = new string[] { "Sangeen Khan", "Jhon", "Wasim", "Alexander", "Afridi" };
      string text = "I am Sangeen Khan and i am friend Jhon. Jhon is friend of Wasim.";
      
      foreach(string name in names)
      {
          text = text.Replace(name, "'Name'");
      }
      
      int matches = Regex.Matches(Regex.Escape(text), "'Name'").Count;
      

      【讨论】:

      • 我亲爱的朋友,列表正在从数据库中加载,当我从数据库中加载列表时,您的代码不起作用
      • @SangeenKhan 然后你应该调试你的代码以查看从数据库加载它时列表中的内容......
      猜你喜欢
      • 1970-01-01
      • 2020-12-06
      • 1970-01-01
      • 2015-08-15
      • 1970-01-01
      • 2015-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多