【问题标题】:How can I use indexof and substring to find words in a string?如何使用 indexof 和 substring 在字符串中查找单词?
【发布时间】:2020-09-13 21:15:24
【问题描述】:

在构造函数中:

var tempFR = File.ReadAllText(file);
GetResults(tempFR);

然后:

private List<string> GetResults(string file)
            {
                List<string> results = new List<string>();

                string word = textBox1.Text;
                string[] words = word.Split(new string[] { ",," }, StringSplitOptions.None);

                for(int i = 0; i < words.Length; i++)
                {
                    int start = file.IndexOf(words[i], 0);
                    results.Add(file.Substring(start));
                }

                return results;
            }

words 在这种情况下包含 3 个单词 System , public , test 我想找到文件中的所有单词并使用 indexof 和 substring 将它们添加到列表结果中。

现在开始值的方式一直是-1。

清除一些东西。 这是 textBox1 的屏幕截图: 这就是为什么我使用两个逗号来分割和获取单词的原因。

这个屏幕截图显示了从 textBox1 中拆分出来的单词:

这是文件字符串内容:

我想将文件中的所有单词添加到列表结果中。 查看最后一个屏幕截图时,应该有 11 个结果。 三倍词使用三倍词系统五倍词公共。

但是变量 start 是 -1

更新:

尝试过 Barns 解决方案,但对我来说效果不佳。 首先是进行搜索的代码,然后遍历文件并报告给后台工作人员:

int numberofdirs = 0;
        void DirSearch(string rootDirectory, string filesExtension, string[] textToSearch, BackgroundWorker worker, DoWorkEventArgs e)
        {
            List<string> filePathList = new List<string>();
            int numberoffiles = 0;
            try
            {
                filePathList = SearchAccessibleFilesNoDistinct(rootDirectory, null, worker, e).ToList();
            }
            catch (Exception err)
            {

            }
            label21.Invoke((MethodInvoker)delegate
                    {
                        label21.Text = "Phase 2: Searching in files";
                    });
            MyProgress myp = new MyProgress();
            myp.Report4 = filePathList.Count.ToString();
            foreach (string file in filePathList)
            {
                try
                {
                    var tempFR = File.ReadAllText(file);

                    _busy.WaitOne();
                    if (worker.CancellationPending == true)
                    {
                        e.Cancel = true;
                        return;
                    }

                    bool reportedFile = false;

                    for (int i = 0; i < textToSearch.Length; i++)
                    {
                        if (tempFR.IndexOf(textToSearch[i], StringComparison.InvariantCultureIgnoreCase) >= 0)
                        {
                            if (!reportedFile)
                            {
                                numberoffiles++;

                                myp.Report1 = file;
                                myp.Report2 = numberoffiles.ToString();
                                myp.Report3 = textToSearch[i];
                                myp.Report5 = FindWordsWithtRegex(tempFR, textToSearch);
                                backgroundWorker1.ReportProgress(0, myp);
                                reportedFile = true;
                            }
                        }
                    }
                    numberofdirs++;
                    label1.Invoke((MethodInvoker)delegate
                    {
                        label1.Text = string.Format("{0}/{1}", numberofdirs, myp.Report4);
                        label1.Visible = true;
                    });
                }
                catch (Exception err)
                {

                }
            }
        }

我已经在 textToSearch 中有 words 数组,在 tempFR 中有文件内容,然后我使用 Barns 的第一个解决方案:

private List<string> FindWordsWithtRegex(string filecontent, string[] words)
        {
            var res = new List<string>();

            foreach (var word in words)
            {
                Regex reg = new Regex(word);
                var c = reg.Matches(filecontent);
                int k = 0;
                foreach (var g in c)
                {
                    Console.WriteLine(g.ToString());
                    res.Add(g + ":" + k++);
                }
            }
            Console.WriteLine("Results of FindWordsWithtRegex");
            res.ForEach(f => Console.WriteLine(f));
            Console.WriteLine();

            return res;
        }

但是我在 List res 中得到的结果与 Barns solution/s 中的输出不同这是我得到的第一个文件的 List res 的结果:

在这种情况下,两个词system和using,但它只找到using 3次,但文件内容中也有system 3次。并且输出格式与 Barns 解决方案中的不同:

【问题讨论】:

  • 您的 split 参数中应该只有 1 个逗号。你想在任何时候分割字符串,只要有一个逗号,而不是遇到双逗号。
  • @itsme86 单词很好,我得到了所有单词。我之所以使用双逗号,是因为当我搜索我正在使用的多个单词时,它在 textBox1.Text 中就是这样,将它们分隔在 textBox1 中,这就是我使用的原因两个逗号。单词很好,我在 textBox1 中得到了 3 个单词。
  • @BenziAvrumi 文本文件应包含正常句子,单词之间有空格。你是说你的 textbox1 有 System,,public,,test 没有空格?那是对的吗?因为如果是这样,这段代码就可以工作,words.Length 将是 2 而不是 -1
  • 这是某种家庭作业吗?为什么要强制使用IndexOf?为什么要创建单词的List 而不是找到“单词”中每个单词的次数的List?根据给出的信息,{"using:3", "System:3", "public:5"} 的结果似乎更有意义。
  • 听起来你需要两个 foreach 循环。每行一个,每个单词一个,因为您想为每个单词一次又一次地搜索同一行。改用var tempFR = File.ReadAllLines(file); 和两个foreach 建议。最好使用流阅读器逐行搜索,而不是将所有内容加载到内存中。顺便说一句,输出是什么样的?只是想知道。

标签: c# winforms


【解决方案1】:

这里是使用Regex 代替IndexOf 的替代方法。注意我已经创建了自己的字符串来解析,所以我的结果会有点不同。


编辑

    private List<string> FindWordsWithCountRegex(string filecontent, string[] words)
    {
        var res = new List<string>();

        foreach (var word in words)
        {
            Regex reg = new Regex(word, RegexOptions.IgnoreCase);
            var c = reg.Matches(filecontent).Count();
            res.Add(word + ":" + c);
        }

        return res;
    }

【讨论】:

  • 我尝试了您的第一个解决方案,但输出格式和结果错误。我用我所做的以及如何在我的代码中使用您的解决方案来编辑​​我的问题。
  • @BenziAvrumi :: 我需要一点时间来查看您编辑的代码。感谢您的尝试。
  • 好的。我看过你的代码。您能否验证string[]“words”是否包含您期望的所有字符串(“using”、“System”),尤其是“System”大写而不是“system”?
  • 是的,words 包含 system 和 using first system 然后 using 和 system 不是大写的(也许小写和大写都更好?)但我确认你的要求。跨度>
  • @BenziAvrumi :: 我已将代码更改为为结果{"using:5", "System:5"... 生成List 的变体,我让它忽略大小写。
【解决方案2】:

简单更改这部分并使用单个字符,通常是空格而不是逗号:

string[] words = word.Split(' ');

【讨论】:

    【解决方案3】:
    int start = file.IndexOf(words[i],0);
    

    如果找不到单词,则开头将是 -1
    MSDN: IndexOf(String, Int32)

    for(int i = 0; i < words.Length; i++)
    {
        int start = file.IndexOf(words[i], 0);
        // only add to results if word is found (index >= 0)
        if (start >= 0) results.Add(file.Substring(start));
    }
    

    如果你想要单词的所有外观,你需要一个额外的循环

    int fileLength = file.Length;
    for(int i = 0; i < words.Length; i++)
    {
        int startIdx = 0;
        while (startIdx < fileLength ){
            int idx = file.IndexOf(words[i], startIdx]);
            if (start >= 0) {
                // add to results
                results.Add(file.Substring(start));
                // and let Word-search continue from last found Word Position Ending
                startIdx = (start + words.Length);
            }
    
        }
        int start = file.IndexOf(words[i], 0);
        // only add to results if word is found (index >= 0)
        if (start >= 0) results.Add(file.Substring(start));
    }
    

    也许你想要一个不区分大小写的搜索
    file.IndexOf(words[i], 0, StringComparison.CurrentCultureIgnoreCase); MSDN: StringComparer Class

    【讨论】:

      猜你喜欢
      • 2014-11-04
      • 2021-01-09
      • 2015-03-03
      • 2016-12-01
      • 1970-01-01
      • 2013-05-21
      • 2016-02-03
      • 1970-01-01
      • 2018-07-22
      相关资源
      最近更新 更多