Как я могу использовать indexof и substring для поиска слов в строке? - PullRequest
0 голосов
/ 27 мая 2020

В конструкторе:

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;
            }

слов в данном случае содержит 3 слова System, publi c, test Я хочу найти все слова в файл и добавьте их в список результатов, используя indexof и substring.

Теперь начальное значение всегда равно -1.

Чтобы очистить некоторые вещи. Это снимок экрана textBox1: Вот почему я использую две запятые для разделения и получения слов.

textBox1

На этом снимке экрана показаны слова после разделения их из textBox1:

Getting the words is fine with two commas

И это содержимое строки файла:

file content

Я хочу добавить в список результатов все слова в файле. При просмотре последнего скриншота должно быть 11 результатов. Три раза слово, в котором используется три раза система слов, пять раз слово publi c.

, но начало переменной - -1

Обновление:

Пробное решение Barns / s, но для меня это не работает. Сначала код, который выполняет поиск, а затем l oop по файлам и сообщает backgroundworker:

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 и содержимое файла в 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, это результаты, которые я получаю Res List для первого файла :

В этом случае система из двух слов и использование, но он обнаружил только использование 3 раза, но в содержимом файла также есть система 3 раза. и выходной формат не такой, как в решениях Barns:

Output is wrong

Ответы [ 3 ]

2 голосов
/ 27 мая 2020

Альтернативный вариант - использовать Regex вместо IndexOf. Примечание. Я создал свою собственную строку для синтаксического анализа, поэтому мои результаты будут немного другими.


EDIT

    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;
    }
1 голос
/ 27 мая 2020
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));
}

Если вы хотите, чтобы все выглядело из слов вам нужно дополнительное l oop

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));
}

Может быть, вам нужен caseinsensitiv поиск
file.IndexOf(words[i], 0, StringComparison.CurrentCultureIgnoreCase); MSDN: StringComparer Class

1 голос
/ 27 мая 2020

Просто измените эту часть и используйте один символ, как правило, пробел, а не запятую:

string[] words = word.Split(' ');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...