2

ユーザーが動画にコメントを残すためのポップアップ フォームがあります。人々がメッセージを入力するフォーム内には、冒涜的なフィルターが配置されています。それは正常に機能し、メッセージ内にある場合はその単語をキャッチします。私の質問は、キャッチされた単語を強調表示して、どれが冒とく的であると見なされたかをユーザーが確認できるようにする方法があるかどうかです。

形成され、フィルターを通過するメッセージは次のとおりです。

    if (context.Request["postform"] == "1")
    {
        ProfanityFilter filter = new ProfanityFilter();

        // IF NEITHER THE MESSAGE OR FIRSTNAME CONTAINS ANY PROFANITY IN THEM
        if (filter.containsProfanity(context.Request["message"]) == false && filter.containsProfanity(context.Request["first_name_submitter"]) == false)
        {
            videomessage myVideoMessage = new videomessage();

            myVideoMessage.video_id = context.Request["video_id"];
            myVideoMessage.first_name_submitter = context.Request["first_name_submitter"];
            myVideoMessage.last_initial_submitter = context.Request["last_initial_submitter"];
            myVideoMessage.message = context.Request["message"];
            myVideoMessage.status = "0";

            myVideoMessage.Save();

            return_success = "1";                
        }
        else
        {
            return_success = "0";
            return_errormessage = "<span>Contains profanity</span>";
        }                
    }

ProfanityFilter クラスは次のとおりです。

public class ProfanityFilter
{
    // ***********************************************************************
    // CONSTRUCTORS
    public ProfanityFilter()
    {
    }
    // ***********************************************************************



    // ************************************************************************
    // METHOD: containsProfanity
    public bool containsProfanity(string checkStr)
    {
        bool badwordpresent = false;

        string[] inStrArray = checkStr.Split(new char[] { ' ' });

        string[] words = this.profanityArray();

        // LOOP THROUGH WORDS IN MESSAGE
        for (int x = 0; x < inStrArray.Length; x++)
        {
            // LOOP THROUGH PROFANITY WORDS
            for (int i = 0; i < words.Length; i++)
            {
                // IF WORD IS PROFANITY, SET FLAG AND BREAK OUT OF LOOP
                //if (inStrArray[x].toString().toLowerCase().equals(words[i]))
                if( inStrArray[x].ToLower() == words[i].ToLower() )
                {
                    badwordpresent = true;
                    break;
                }
            }
            // IF FLAG IS SET, BREAK OUT OF OUTER LOOP
            if (badwordpresent == true) break;
        }

        return badwordpresent;
    }
    // ************************************************************************




    // ************************************************************************
    // METHOD: profanityArray()
    // METHOD OF PROFANITY WORDS
    private string[] profanityArray()
    {

        string[] words = { // ARRAY OF WORDS };
return words;
}
}

else単語を強調するために何かを追加する方法はありますか? それとも、色を黒から赤に変えるだけですか?

前もって感謝します!

4

3 に答える 3

8

それを行う最も簡単な方法は、冒とく的な単語のすべての出現をその単語を表すマークアップに置き換えることです。

<span class="profane">PUT_THE_WORD_HERE</span>

CSS にルールを含める

span.profane

ある種の視覚的な表示を提供します。

懸念事項の分離に努める必要があるため、ProfanityFilter 自体でこのマークアップを行うことはありません。これを行う巧妙な方法は、ProfanityFilter が処理する文字列フラグメントごとにイベントを提供することです。そのコールバックは、単語が冒涜的であるかどうか、およびフラグメント自体についての指標を提供します。イベント ハンドラーでは、各イベントのフラグメントを追加して元のフレーズを再構築し、それが不適切な場合はマークアップで囲みます。そのイベントは、完全な元のフレーズを再作成できるように、空白と句読点も受け取る必要があります。

段階:

"This website sucks.  Really!"

イベント:

"This", profane: false
" ", profane: false
"website", profane: false
" ", profane: false
"sucks", profane: true
".  ", profane: false
"Really", profane: false
"!", profane: false

それほど複雑にしたくない場合は、ProfanityFilter が検出した冒涜的な単語のリストを返し、グローバル検索を実行して元のフレーズを置き換えることができます。

交換:

public bool containsProfanity(string checkStr)

public class ProfanityResult
{
    public bool Profane { get; set; }
    public List<string> ProfanityWords { get; set; }
}


public ProfanityResult containsProfanity(string checkStr)

アップデート

2 番目のオプションを使用すると仮定すると、次のようになります。

string markedMessage = context.Request["message"];
if (result.Profane)
{
    foreach (string word in result.ProfanityWords)
    {
        markedMessage = markedMessage.Replace(
                           word, 
                           "<span class=\""profane\"">" + word + "</span>");
    }    
}

このアプローチは、置換ごとに文字列の新しいコピーを作成するため、非常に効率的ではありませんが、短いコメントや投稿について考えている場合は、非効率性に気付かないでしょう.

于 2012-09-27T19:12:06.930 に答える
3

次のようなことができます。

public string containsProfanity(string checkStr)
{
    // .....
    bool badwordpresent = false;

    // LOOP THROUGH WORDS IN MESSAGE
    for (int x = 0; x < inStrArray.Length; x++)
    {
        // LOOP THROUGH PROFANITY WORDS
        for (int i = 0; i < words.Length; i++)
        {
            if( inStrArray[x].ToLower() == words[i].ToLower() )
            {
                inStrArray[x] = "<span class=\"profane\">" + inStrArray[x] + "</span>";
                badwordpresent = true;
                break;
            }
        }
        // if (badwordpresent == true) break; <- removed
    }

    return badwordpresent ? String.join(" ", inStrArray) : null;
}

編集: 悪い単語が見つからない場合は null を返します。

于 2012-09-27T19:56:46.113 に答える
1

少量のリファクタリングでこれを達成できますが、Eric Jの投稿のように、より良いリファクタリングを使用します。

public class ProfanityFilter
{

  public bool containsProfanity(string checkStr, ref List<string> badWords)
  {
    // ...
    if (String.Compare(inStrArray[x], words[i], StringComparison.OrdinalIgnoreCase) == 0)
    {
      badwordpresent = true;
      badWords.Add(inStrArrary[x]);         
    }
    // ...
  }
}

else冒とく的な表現を扱うブロックの代わりに、message最初first_name_submitterにとを扱い、冒とく的な表現が見つかった場合はメソッドから抜け出します。

List<string> badWords = new List<string>();
if (filter.containsProfanity(context.Request["message"], ref badWords))
{
   return_errormessage = string.Format("<span style=\"color:red\">Message contains the following bad word(s): {0}</span>", 
                          HttpUtility.HtmlEncode(String.Join(" ", badWords.ToArray()));
   return_success = "0";
   return; // break out of method
}

// save video message

return_success = "1"; 
于 2012-09-27T19:42:50.800 に答える