Можно попробовать Код:: Блоки , который является лучшим IDE и идет с MinGW GCC! Я использовал его и его просто слишком хороший бесплатный IDE для C/C++.
Пока что это выглядит как хороший кандидат для 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*
Объяснение
Переходите от символа к символу к строке следующим образом: (своего рода псевдокод)
array words = {} // empty array
string word = "" // empty word
bool in_quotes = false
for char c in search string:
if in_quotes:
if c is '"':
append word to words
word = "" // empty word
in_quotes = false
else:
append c to word
else if c is '"':
in_quotes = true
else if c is ' ': // space
if not empty word:
append word to words
word = "" // empty word
else:
append c to word
// Rest
if not empty word:
append word to words
I was just trying to figure out how to do this a few days ago. I ended up using Microsoft.VisualBasic.FileIO.TextFieldParser which did exactly what I wanted (just set HasFieldsEnclosedInQuotes to true). Sure it looks somewhat odd to have "Microsoft.VisualBasic" in a C# program, but it works, and as far as I can tell it is part of the .NET framework.
To get my string into a stream for the TextFieldParser, I used "new MemoryStream(new ASCIIEncoding().GetBytes(stringvar))". Not sure if this is the best way to do it.
Edit: I don't think this would handle your "-" requirement, so maybe the RegEx solution is better