Подобная Google токенизация поискового запроса и строковое разделение

Можно попробовать Код:: Блоки , который является лучшим IDE и идет с MinGW GCC! Я использовал его и его просто слишком хороший бесплатный IDE для C/C++.

9
задан jamesaharvey 10 December 2009 в 18:54
поделиться

3 ответа

Пока что это выглядит как хороший кандидат для 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*

Объяснение

  1. Если возможно, сопоставьте знак минус, за которым следует «все, за которым следует все до следующего»
  2. В противном случае сопоставьте «с последующим всем до следующего»
  3. В противном случае сопоставьте - с последующим любым словом символов
  4. В противном случае сопоставьте столько символов слова, сколько сможете
  5. Поместите результат в группу
  6. Поглотите все следующие пробелы
13
ответ дан 4 December 2019 в 13:47
поделиться

Переходите от символа к символу к строке следующим образом: (своего рода псевдокод)

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
1
ответ дан 4 December 2019 в 13:47
поделиться

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

1
ответ дан 4 December 2019 в 13:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: