0

禁止されている単語を含む文字列のリストがあります。文字列に禁止されている単語が含まれているかどうかを確認し、文字列から削除する効率的な方法は何ですか?現時点では、私はこれを持っています:

cleaned = String.Join(" ", str.Split().Where(b => !bannedWords.Contains(b,
                            StringComparer.OrdinalIgnoreCase)).ToArray());

これは、単一の禁止された単語に対しては正常に機能しますが、フレーズに対しては機能しません(例more than one word)。のインスタンスmore than one wordもすべて削除する必要があります。私が試してみようと思った別の方法は、ListのContainsメソッドを使用することですが、これはブール値のみを返し、一致する単語のインデックスは返しません。一致する単語のインデックスを取得できれば、次のように使用できます。String.Replace(bannedWords[i],"");

4

4 に答える 4

2

定義が競合しているため、機能しません。

more than one word空白で分割できないようなサブセンテンスを探したいとき。あなたは頼る必要がありますString.IndexOf()

于 2012-04-07T20:29:33.230 に答える
2

単語の一部が削除されるため、 simpleString.Replaceは機能しません。「sex」が禁止語で、禁止されていない「sextet」という単語がある場合は、そのままにしておく必要があります。

を使用Regexすると、テキスト内の単語やフレーズ全体を検索できます

string text = "A sextet is a musical composition for six instruments or voices.".
string word = "sex";
var matches = Regex.Matches(text, @"(?<=\b)" + word + @"(?=\b)");

この場合、matches コレクションは空になります。

Regex.Replaceメソッドを使用できます

foreach (string word in bannedWords) {
    text = Regex.Replace(text, @"(?<=\b)" + word + @"(?=\b)", "")
}

注:次のRegexパターンを使用しました

(?<=prefix)find(?=suffix)

ここで、'prefix' と 'suffix' は両方とも\bで、単語の始まりと終わりを示します。

禁止された単語やフレーズに特殊文字を含めることができる場合は、 でエスケープする方が安全Regex.Escape(word)です。


@zmbqのアイデアを使用すると、Regex一度パターンを作成できます

string pattern =
    @"(?<=\b)(" +
    String.Join(
        "|",
        bannedWords
            .Select(w => Regex.Escape(w))
            .ToArray()) +
     @")(?=\b)";
var regex = new Regex(pattern); // Is compiled by default

そして、それをさまざまなテキストに繰り返し適用します

string result = regex.Replace(text, "");
于 2012-04-07T20:46:16.840 に答える
1

求めているのがパフォーマンスなら、1 回のセットアップ時間ではなく、継続的なパフォーマンスを気にしていると思います。したがって、禁止されているすべての式を含む 1 つの巨大な正規表現を作成し、それがコンパイルされていることを確認します。これがセットアップです。

次に、それをテキストと照合して、すべての一致を空白または置換したいものに置き換えます。

この理由は、大きな正規表現は、この問題を処理するために手動で作成する有限状態オートマトンに匹敵するものにコンパイルする必要があるためです。したがって、非常にうまく動作するはずです。

于 2012-04-07T20:32:04.710 に答える
0

メソッド を使用して、禁止単語のリストを反復処理し、文字列内の各単語を調べてみませんかstring.IndexOf。たとえば、次のコードを使用して、禁止された単語やフレーズを削除できます。

myForbWords.ForEach(delegate(string item) {
    int occ = str.IndexOf(item);
    if(occ > -1) str = str.Remove(occ, item.Length);
});

myForbWords のタイプは ですList<string>

于 2012-04-07T20:49:21.740 に答える