搜索匹配项时是否可以使用列表作为模式?

Is it possible to use a list as a pattern when searching for matches?

我基本上是将带有不同变量的罪犯添加到报告中,它看起来像这样:

reports.Add(new Report(tbxCriminalSuspicion.Text, 
   (new Criminal(Ordformatering(tbxName.Text), Ordformatering(tbxSex.Text), int.Parse(tbxAge.Text),
   double.Parse(tbxHeight.Text), Ordformatering(tbxHairColor.Text)))));

然后我创建了另一个字符串,我想用它来在罪犯之间进行搜索。您在文本框中输入内容,它会按以下方式放入列表中:

string allSearchWords = tbxSearchWords.text;
List<string> splitSearchWords = new List<string>();
allSearchWords = allSearchWords.Replace(" ", "");
splitSearchWords = allSearchWords.Split(',').ToList();

现在我有了一个单词列表,我可以通过以下方式搜索我的罪犯:

splitSearchWords.All((criminal).Contains);

但是,如果情况如下:

罪犯1:18岁,176cm

罪犯2:34岁,180cm

两名罪犯都会出现在列表框中,即使只有一个是 18 岁。换句话说,是否可以使用列表作为模式来搜索完全匹配?可以附上一些代码。

List<Report> reports = new List<Report>();
List<string> splitSearchWords = new List<string>();

        private void btnSearch_Click(object sender, EventArgs e)
        {
            lbxLista.Items.Clear();

            if (string.IsNullOrWhiteSpace(tbxSearchWords.Text))
            {
                MessageBox.Show("Vänligen fyll i dina sökord innan du söker enligt \"Sökord, sökord, sökord, ...\"",
                        "Felinmatning", MessageBoxButtons.OK, MessageBoxIcon.Information);
                     //Just a check so that the searchbox isn't empty!!!!
            }

            else
            {
                string allSearchWords = tbxSearchWords.Text;
                allSearshWords = allSearshWords.Replace(" ", "");
                splitSearchWords = allSearchWords.Split(',').ToList();

                for (int i = 0; i < reports.Count; i++)
                {
                    if(ContainsSearchWord(reports[i].GetData(), splitSearchWords))
                    {
                        lbxLista.Items.Add(reports[i].ToString());
                    }
                }
            }
        }

        public static bool ContainsSearchWord(string stringToTest, List<string> searchedWords)
        {
            return searchedWords.All((stringToTest).Contains);
        }

类,举报与犯罪:

class Report
    {
        public string GetData()
        {
            return "" + criminal.criminalName + " " + criminal.criminalSex +
                " " + criminal.criminalAge + " " +
                criminal.criminalHeight + " " + criminal.criminalHairColor;
        }
    }

class Criminal
    {
        private string privatCriminalName;
        private string privatCriminalSex;
        private int privatCriminalAge;
        private double privatCriminalHeight;
        private string privatCriminalHairColor;

        public Criminal(string mCriminalName, string mCriminalSex,
            int mCriminalAge, double mCriminalHeight, string mCriminalHeightColor)
        {
            this.criminalName = mCriminalName;
            this.criminalSex = mCriminalSex;
            this.criminalAge = mCriminalAge;
            this.criminalHeight = mCriminalHeight;
            this.criminalHairColor = mCriminalHeightColor;
        }
        //Then I have properties to access these from outside the class but removed due to being messy and lengthy in post.
    }

Layout of the program, ANMÄLAN is where you enter to register a crime, SÖK is where you search for reports and SÖKRESULTAT is where the matching reports will shop up

请原谅这么长的 post,10 小时后我就迷路了。

is it possible to search for an exact match using a list as a pattern?

在这里摸索一下,但如果你有这些字符串:

criminals = new string[] {
  "Criminal 1: 18 years old, 176 cm",
  "Criminal 2: 34 years old, 180 cm"
}

并且用户键入此作为他们的搜索词:

18,old

而你想确保“18”不匹配罪犯2身高中的180,那么你可以使用正则表达式:

var searchTerms = "18,old".Split(',').Select(s => $@"\b{s}\b").ToArray();


criminals.Where(c => searchTerms.All(st => Regex.IsMatch(c, st)));

这将 return 只有字符串匹配所有正则表达式的犯罪分子。

严重的是,您的 searchTerms 已变成一个数组,如:

new string[] { @"\b18\b", @"\bold\b" };

\b 表示“单词边界”- zero-width 字符位于“非单词字符”之间,例如 space、标点符号、end/start 字符串等,以及您要查找的字符

因此\b18\b会匹配“he is 18 years old”和“it is 18”,但不会匹配“it is 180 years old”,也不是“它是 218 岁”等等


如果你想在没有正则表达式的情况下做到这一点,你可以在 space:

上拆分犯罪字符串
var searchTerms = "18,old".Split(',')

criminals.Where(c => { 
  var words = c.Split(); 
  return searchTerms.All(st => words.Contains(st)); 
} );

但没那么复杂;它会在 words 中有 old,,所以我在 old 上面的搜索词找不到匹配项。如果你想反击,你必须拆分更多东西(标点符号等)不仅仅是 space..


现在,关于区分大小写...

您可以使用数组而不是使用字符串来测试模式。该数组将包含每个特征和犯罪作为单独的 string 值。这样,您仍然可以使用 Contains,但它会单独测试字符串,而不是它们的子字符串。

public static bool ContainsSearchWord(string stringToTest, List<string> searchedWords) {
        return searchedWords.All((stringToTest.Split(' ')).Contains);
}

您甚至不必为此创建变量,只需对已有的变量使用 Split()