C# C全文搜索字符串格式:字符串删除所有相邻的重复项,并附加“和”“或”

C# C全文搜索字符串格式:字符串删除所有相邻的重复项,并附加“和”“或”,c#,sql-server,full-text-search,duplicate-removal,c#-5.0,C#,Sql Server,Full Text Search,Duplicate Removal,C# 5.0,我正在寻找一个c语言的解决方案,在调用SQL查询之前格式化用户输入的搜索字符串 在表上启用了全文索引,查询如下所示 select [title] from publications where contains([title], @searchString) 主要问题: 示例: 输入=>输出 a) "oyster and oyster or fish and clean water" => "oyster or fish and clean OR water"<br> b

我正在寻找一个c语言的解决方案,在调用SQL查询之前格式化用户输入的搜索字符串

在表上启用了全文索引,查询如下所示

select [title] from publications where contains([title], @searchString)
主要问题:

示例: 输入=>输出

a)   "oyster and oyster or fish and clean water" => "oyster or fish and clean OR water"<br>
b)   "oyster and and fish and clean water" => "oyster and fish and clean OR water"<br>
b-1) "oyster oyster fish fish clean and water"=> "oyster or fish or clean and water"
c)   "oyster fish" => "oyster or fish"<br>
c-1) "oyster fish clean water" => "oyster or fish or clean or water"
d)   "oyster and" => "oyster"<br>
e)   "oyster and oyster" => "oyster"<br>
在案例a、b和b-1中,当前代码wch失败;为c-1、d、e工作

 string Format(string str)
    {
        List<string> searchKeywords = new List<string> { "and", "or" };
        //convert to lower case
        str = str.Replace(",", " ").ToLower();

        Regex regex = new Regex(@"[ ]{2,}", RegexOptions.None);
        //remove extra whitespace with space
        str = regex.Replace(str, @" ");

        //split string 
        string[] strArray = str.Split(' ');

        List<string> outputArray = new List<string>();
        string output = "";
        string prevStr = "";
        string currStr = "";
        bool keywordFlag = false;
        bool duplicateFlag = false;

        //remove adjacent keyword or same words
        foreach (var item in strArray)
        {
            currStr = item.Trim();
            keywordFlag = searchKeywords.Contains(prevStr) && searchKeywords.Contains(currStr);
            duplicateFlag = outputArray.Contains(currStr) && !searchKeywords.Contains(currStr);
            if (!currStr.Equals(prevStr) && !keywordFlag && !duplicateFlag)
            {
                outputArray.Add(currStr);
                prevStr = currStr;
            }
        }

        if (outputArray.Count() == 2 && searchKeywords.Contains(outputArray[1]))
        {
            outputArray.Remove(outputArray[1]);
        }

        output = string.Join(" ", outputArray);
        if (output.Contains(" ") && !output.Contains("and") && !output.Contains("or"))
        {
            return string.Join(" or ", output.Split(' ').Select(I => I.Trim()));
        }
        return output;
    }
![电流输出][1]

牡蛎、鱼和干净的水 牡蛎、鱼和干净的水 牡蛎鱼要干净、干净 牡蛎、鱼或清水 牡蛎还是鱼 牡蛎
oyster

既然您还没有展示到目前为止所做的工作,我假设您还没有开始研究解决方案,那么这里有一个高级算法:

在这种情况下,请使用String.Split“”按每个空格分割searchstring

在生成的字符串数组上使用foreach循环,并使用字符串连接来完成,如果之前已经使用了一个单词,则不需要将其添加到生成的字符串中。 如果前一个单词是或,而当前单词也是,则不要将其添加到结果字符串中。 如果前一个单词不是或,而当前单词不是,请将或添加到结果字符串中

编辑:现在代码已经发布了,我可以看到哪里出了问题

这是有条件的:

    if (output.Contains(" ") && !output.Contains("and") && !output.Contains("or"))
    {
        return string.Join(" or ", output.Split(' ').Select(I => I.Trim()));
    }
仅当输出不包含and或or的任何实例时才会调用

进行检查,查看是否需要在foreach循环中添加或需要添加,并去掉该条件

e、 g:

另外,当您检查数组中是否只有2个令牌时,您只需要考虑它们是否在一个单词后放入或,如果它们将或Oyster作为输入字符串,会发生什么情况?结果字符串将是或

您需要对此进行说明:

            if (outputArray.Count() == 2)
            {
                if(searchKeywords.Contains(outputArray[0]))
                    outputArray.Remove(outputArray[0]);
                else if(searchKeywords.Contains(outputArray[1]))
                    outputArray.Remove(outputArray[1]);
            }

不确定这个答案是否正确,非常感谢@saggio的建议

private string FormatSearchString(string str)
    {
        List<string> searchKeywords = new List<string> { "and", "or" };
        //convert to lower case
        str = str.Replace(",", " ").ToLower();

        Regex regex = new Regex(@"[ ]{2,}", RegexOptions.None);
        //remove extra whitespace with space
        str = regex.Replace(str, @" ");

        //split string 
        string[] strArray = str.Split(' ');

        List<string> outputArray = new List<string>();
        string output = "";
        string prevStr = "";
        string currStr = "";
        bool keywordFlag = false;
        bool duplicateFlag = false;

        //remove adjacent keyword or same words
        foreach (var item in strArray)
        {
            currStr = item.Trim();
            keywordFlag = searchKeywords.Contains(prevStr) && searchKeywords.Contains(currStr);
            duplicateFlag = outputArray.Contains(currStr) && !searchKeywords.Contains(currStr);
            if (!currStr.Equals(prevStr) && !keywordFlag && !duplicateFlag)
            {
                if (!searchKeywords.Contains(prevStr) && !searchKeywords.Contains(currStr) && prevStr != "")
                {
                    outputArray.Add("or");
                }
                outputArray.Add(currStr);
                prevStr = currStr;
            }
        }

        if (outputArray.Count() == 2)
        {
            if (searchKeywords.Contains(outputArray[0]))
                outputArray.Remove(outputArray[0]);
            else
                outputArray.Remove(outputArray[1]);
        }

        output = string.Join(" ", outputArray);

        return output;
    }

您尝试过什么?您尝试的解决方案有哪些问题?仅仅发布需求列表不是一个合适的问题。这只是一个程序的描述,而不是一个问题。如果你不展示你迄今为止所做的尝试,详细说明问题的具体内容,以及你希望得到的答案,我们无法确定你遇到了什么问题。如果没有这些,听起来像是你要求我们为你做的。对不起,这是stackoverflow上的第一篇文章,发布了我的代码和输出。根据发布的代码更新了答案谢谢你的建议,这很有帮助。如果outputArray.count==2{if searchKeywords.ContainsoutputArray[0]outputArray.RemoveoutputArray[0];else outputArray.RemoveoutputArray[1];}将foreach循环更新为上文和outputArray.Count==2的条件,并删除最后一个条件,它应该可以工作。我使用提供的示例输入运行它,得到了预期的结果results@BeingDev此外,如果这对您有效,请将此答案标记为已接受,以帮助可能有类似问题的其他人,这就是StackOverflow的工作原理
            if (outputArray.Count() == 2)
            {
                if(searchKeywords.Contains(outputArray[0]))
                    outputArray.Remove(outputArray[0]);
                else if(searchKeywords.Contains(outputArray[1]))
                    outputArray.Remove(outputArray[1]);
            }
private string FormatSearchString(string str)
    {
        List<string> searchKeywords = new List<string> { "and", "or" };
        //convert to lower case
        str = str.Replace(",", " ").ToLower();

        Regex regex = new Regex(@"[ ]{2,}", RegexOptions.None);
        //remove extra whitespace with space
        str = regex.Replace(str, @" ");

        //split string 
        string[] strArray = str.Split(' ');

        List<string> outputArray = new List<string>();
        string output = "";
        string prevStr = "";
        string currStr = "";
        bool keywordFlag = false;
        bool duplicateFlag = false;

        //remove adjacent keyword or same words
        foreach (var item in strArray)
        {
            currStr = item.Trim();
            keywordFlag = searchKeywords.Contains(prevStr) && searchKeywords.Contains(currStr);
            duplicateFlag = outputArray.Contains(currStr) && !searchKeywords.Contains(currStr);
            if (!currStr.Equals(prevStr) && !keywordFlag && !duplicateFlag)
            {
                if (!searchKeywords.Contains(prevStr) && !searchKeywords.Contains(currStr) && prevStr != "")
                {
                    outputArray.Add("or");
                }
                outputArray.Add(currStr);
                prevStr = currStr;
            }
        }

        if (outputArray.Count() == 2)
        {
            if (searchKeywords.Contains(outputArray[0]))
                outputArray.Remove(outputArray[0]);
            else
                outputArray.Remove(outputArray[1]);
        }

        output = string.Join(" ", outputArray);

        return output;
    }