到目前为止,这看起来像是 RegEx 的一个很好的候选者。如果它变得更加复杂,那么可能需要更复杂的标记化方案,但除非必要,否则您应该避免使用该路线,因为它的工作量要大得多。(另一方面,对于复杂的模式,正则表达式很快就会变成狗,同样应该避免)。
这个正则表达式应该可以解决您的问题:
("[^"]+"|\w+)\s*
这是其用法的 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;
}
这种方法的真正好处是它可以很容易地扩展以包含您的“-”要求,如下所示:
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;
}
现在我讨厌阅读 Regex 和下一个人一样多,但如果你把它分开,这个很容易阅读:
(
-"[^"]+"
|
"[^"]+"
|
-\w+
|
\w+
)\s*
解释
- 如果可能,匹配一个减号,后跟一个“,然后是所有内容,直到下一个”
- 否则匹配一个 " 后跟所有内容,直到下一个 "
- 否则匹配一个 - 后跟任何单词字符
- 否则匹配尽可能多的单词字符
- 将结果放在一个组中
- 吞下任何后面的空格字符