C#在引号中解析文本

时间:2010-10-15 08:25:31

标签: c# regex parsing

我正在开发一个简单的小搜索机制,我希望允许用户搜索带有空格的文本块。例如,用户可以搜索人的姓名:

姓名:John Smith

然后我"John Smith".Split(' ')成了两个元素{"John","Smith"}的数组。然后我返回所有匹配“John”和“Smith”的记录,然后返回与"John" OR "Smith."匹配的记录,然后返回没有匹配的记录。这不是一个复杂的场景,我有这部分工作。

我现在希望能够允许用户仅返回与“John Smith”匹配的记录

我想使用基本的引用语法进行搜索。因此,如果用户想要搜索“John Smith”或Pocahontas,他们将输入:“John Smith”Pocahontas。术语的顺序绝对无关紧要; “约翰史密斯”并未获得优于波卡洪塔斯的优先权,因为他名列第一。

关于如何解析输入,我有两个主要思路。

A) Using regular expression then parsing stuff (IndexOf, Split)
B) Using only the parsing methods 

我认为一个合乎逻辑的行动方针是用引号找到这些东西;然后将其从原始字符串中删除并将其插入单独的列表中。然后,原始字符串遗留下来的所有内容都可以在空格上分割并插入到单独的列表中。如果有1个引号或奇数,则只需从列表中删除。

如何在正则表达式中找到匹配项?我知道regex.Replace,但我如何迭代匹配并将它们插入到列表中。我知道使用MatchEvaluator委托和linq有一些巧妙的方法可以做到这一点,但我基本上都不知道c#中的正则表达式。

3 个答案:

答案 0 :(得分:1)

编辑:重新回到此标签,并没有意识到这个问题已经回答了......接受的答案更好。


我认为首先用正则表达式引用引号中的东西是个好主意。也许是这样的:

String sampleInput = "\"John Smith\" Pocahontas Bambi \"Jane Doe\" Aladin";

//Create regex pattern
Regex regex = new Regex("\"([^\".]+)\"");

List<string> searches = new List<string>();

//Loop through all matches from regex
foreach (Match match in regex.Matches(sampleInput))
{
    //add the match value for the 2nd group to the list
    //(1st group is the entire match)
    //(2nd group is the first parenthesis group in the defined regex pattern
    //   which in this case is the text inside the quotes)
    searches.Add(match.Groups[1].Value);
}

//remove the matches from the input
sampleInput = regex.Replace(sampleInput, String.Empty);

//split the remaining input and add the result to our searches list
searches.AddRange(sampleInput.Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries));

答案 1 :(得分:0)

使用这样的正则表达式:

string input = "\"John Smith\" Pocahontas";
Regex rx = new Regex(@"(?<="")[^""]+(?="")|[^\s""]\S*");
for (Match match = rx.Match(input); match.Success; match = match.NextMatch()) {
    // use match.Value here, it contains the string to be searched
}

答案 2 :(得分:0)

我需要与Shawn相同的功能,但我不想使用正则表达式。这是一个简单的解决方案,我提出使用Split()而不是正则表达式为其他需要此功能的人。

这是有效的,因为默认情况下,Split方法将在数组中为源字符串中的连续搜索值创建空条目。如果我们拆分引号字符,那么结果就是一个数组,其中偶数索引条目是单个单词,奇数索引条目将是引号短语。

示例:

“John Smith” Pocahontas

结果

item(0) = (empty string)
item(1) = John Smith
item(2) = Pocahontas

1 2 “3 4” 5 “6 7” “8 9”

结果

item(0) = 1 2
item(1) = 3 4
item(2) = 5
item(3) = 6 7
item(4) = (empty string)
item(5) = 8 9

请注意,不匹配的引号会导致从最后一个引号到输入字符串末尾的短语。

    public static List<string> QueryToTerms(string query)
    {
        List<string> Result = new List<string>();

        // split on the quote token
        string[] QuoteTerms = query.Split('"');
        // switch to denote if the current loop is processing words or a phrase
        bool WordTerms = true;

        foreach (string Item in QuoteTerms)
        {
            if (!string.IsNullOrWhiteSpace(Item))
                if (WordTerms)
                {
                    // Item contains words. parse them and ignore empty entries.
                    string[] WTerms = Item.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (string WTerm in WTerms)
                        Result.Add(WTerm);
                }
                else
                    // Item is a phrase.
                    Result.Add(Item);

            // Alternate between words and phrases.
            WordTerms = !WordTerms;
        }
        return Result;
    }