11

Google と同様に、検索クエリをトークン化しようとしています。たとえば、次の検索クエリがあるとします。

the quick "brown fox" jumps over the "lazy dog"

次のトークンを含む文字列配列が必要です。

the
quick
brown fox
jumps
over
the
lazy dog

ご覧のとおり、トークンはスペースを二重引用符で囲みます。

C# でこれを行う方法の例を探していますが、できれば正規表現を使用しないでください。

また、これを拡張して他の特殊文字を処理する方法を知りたいです。たとえば、用語の前に - を付けて、検索クエリからの除外を強制するなどです。

4

4 に答える 4

15

これまでのところ、これは 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;
}

今、私は次の男と同じくらい正規表現を読むのが嫌いですが、それを分割すると、これは非常に読みやすいです:

(
-"[^"]+"
|
"[^"]+"
|
-\w+
|
\w+
)\s*

説明

  1. 可能であれば、マイナス記号に一致し、その後に " が続き、次の " までのすべてが続きます。
  2. それ以外の場合は、" に続き、次の " までのすべてに一致します。
  3. それ以外の場合は、任意の単語文字が続く - に一致します
  4. それ以外の場合は、できるだけ多くの単語文字に一致します
  5. 結果をグループに入れる
  6. 後続の空白文字をすべて飲み込む
于 2009-12-10T19:07:48.373 に答える
1

私は数日前にこれを行う方法を理解しようとしていました。最終的には、Microsoft.VisualBasic.FileIO.TextFieldParserを使用して、希望どおりの処理を実行しました(HasFieldsEnclosedInQuotesをtrueに設定するだけです)。確かに、C#プログラムに「Microsoft.VisualBasic」が含まれているのは少し奇妙に見えますが、それは機能し、私が知る限り、これは.NETFrameworkの一部です。

文字列をTextFieldParserのストリームに取り込むために、「new MemoryStream(new ASCIIEncoding()。GetBytes(stringvar))」を使用しました。これが最善の方法かどうかはわかりません。

編集:これで「-」要件を処理できるとは思わないので、正規表現ソリューションの方が優れている可能性があります

于 2009-12-10T19:57:44.220 に答える
1

次のように char ごとに文字列に移動します: (一種の擬似コード)

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
于 2009-12-10T19:07:22.343 に答える