类似Google的搜索查询标记化和字符串拆分

jam*_*vey 9 c# search tokenize

我希望将搜索查询标记为类似于Google的操作方式.例如,如果我有以下搜索查询:

the quick "brown fox" jumps over the "lazy dog"
Run Code Online (Sandbox Code Playgroud)

我想要一个包含以下标记的字符串数组:

the
quick
brown fox
jumps
over
the
lazy dog
Run Code Online (Sandbox Code Playgroud)

如您所见,标记用双引号保留空格.

我正在寻找一些如何在C#中执行此操作的示例,最好不使用正则表达式,但是如果这样做最有意义并且性能最高,那就这样吧.

此外,我想知道如何扩展它来处理其他特殊字符,例如,在一个术语的前面放置一个强制从搜索查询中排除等等.

Mic*_*oie 13

到目前为止,这似乎是RegEx的一个很好的候选者.如果它变得更加复杂,那么可能需要更复杂的标记化方案,但除非必要,否则应该避免使用该路由,因为这样做的工作要多得多.(另一方面,对于复杂的模式,正则表达式很快变成了狗,同样应该避免).

这个正则表达式应该解决你的问题:

("[^"]+"|\w+)\s*
Run Code Online (Sandbox Code Playgroud)

以下是其用法的C#示例:

string data = "the quick \"brown fox\" jumps over the \"lazy dog\"";
string pattern = @"(""[^""]+""|\w+)\s*";

MatchCollection mc = Regex.Matches(data, pattern);
foreach(Match m in mc)
{
    string group = m.Groups[0].Value;
}
Run Code Online (Sandbox Code Playgroud)

这种方法的真正好处是它可以很容易地扩展到包含你的" - "要求,如下所示:

string data = "the quick \"brown fox\" jumps over " +
              "the \"lazy dog\" -\"lazy cat\" -energetic";
string pattern = @"(-""[^""]+""|""[^""]+""|-\w+|\w+)\s*";

MatchCollection mc = Regex.Matches(data, pattern);
foreach(Match m in mc)
{
    string group = m.Groups[0].Value;
}
Run Code Online (Sandbox Code Playgroud)

现在我讨厌和下一个人一样阅读正则表达式,但是如果你把它分开,这个很容易阅读:

(
-"[^"]+"
|
"[^"]+"
|
-\w+
|
\w+
)\s*
Run Code Online (Sandbox Code Playgroud)

说明

  1. 如果可能的话匹配一个减号,然后是"后面的所有内容,直到下一个"
  2. 否则匹配"跟随一切直到下一个"
  3. 否则匹配a - 后跟任何单词字符
  4. 否则匹配尽可能多的单词字符
  5. 将结果放在一个组中
  6. 吞下任何后续空格字符