このトピックでは、Discourse の Watched Words 機能で正規表現(regex)を効果的に使用する方法について説明します。
当社のホスティングを利用しているサイトでは、これらの設定は非表示になっています。有料ホスティングプランをご利用のお客様は、
team@discourse.orgまでお問い合わせいただき、Watched Words での正規表現使用をリクエストしてください。
注意: この機能は、無料ホスティングプランでは利用できません。
正規表現(regex)は、検索パターンを定義するための強力なツールです。Discourse サイトの Watched Words 機能で正規表現を使用することで、単語フィルタリングの精度と柔軟性を向上させることができます。
Watched Words で正規表現を使用するには、まず
watched_words_regular_expressionsサイト設定を有効にする必要があります。
正規表現は非常に強力であるため、危険でもあります。誤って記述された正規表現ステートメントは、ユーザーに問題を引き起こす可能性があります。本番環境に移行する前に、本番環境ではないインスタンスで正規表現ステートメントをテストしてください。
正規表現パターンの例
以下は、一般的な正規表現パターンとその活用方法です。
大文字小文字の区別なし
デフォルトでは、Discourse は単語の大文字と小文字の両方の形式に一致します。
thread
これにより、thread、THREAD、thReAd に一致します。
文字の選択肢
文字の選択肢を使用して、一致するパターンを広げることができます。
(t|7)hr(3|e)(4|a)d
これにより、上記のすべてのケースに加え、thr3ad、7hread、thr34d にも一致します。
threads?\b
これにより、thread と threads に一致しますが、threaded や threading には一致しません。
単語境界
正規表現パターンは、意図せずに単語の一部に一致することがあります。部分一致を避けるために、単語境界を使用してください。
\bthreads?\b
これにより、thread と threads に一致しますが、threadlike や unthreading のような一致は避けられます。
Unicode 文字の処理
標準的な単語境界は、Unicode 文字では機能しない場合があります。JavaScript 正規表現で適切に処理されない文字用の境界を作成してください。
gr(ü|ue)(ß|ss)e
これにより、grüße の一般的に綴られるすべての形式(gruesse や GRÜSSE など)に一致します。
Über はブロックしたいが、Übersicht はブロックしたくない場合、\b(ü|ue)ber\b のような単語境界では、JavaScript 正規表現の単語フラグの一部が Unicode 文字を適切に処理できないため、機能しません。代わりに、独自の境界を作成する必要があります。
(?:^|\s)(ü|ue)ber\b
これにより、Über と ueber に適切に一致しますが、Übersicht や uebersicht には一致しません。
意図的な文字置換の検出
ユーザーが文字の代わりに数字や特殊文字を使用した場合の単語を検出するには、以下のようにします。
\bp[a@]ssw[o0]rd\b
これにより、password、p@ssword、passw0rd、p@ssw0rd に一致しますが、mypassword や password123 には一致しません。
間に句読点が入った文字の処理
フィルタを回避するために句読点を挿入する試みを検出するには、以下のようにします。
\bs\W*p\W*a\W*m\b
これにより、spam、s.p.a.m、s-p-a-m に一致しますが、s_p_a_m(アンダースコアは単語文字であるため)、spammy、myspam には一致しません。
複数の単語バリエーションの一致
異なる単語形式で現れる可能性のあるフレーズを一致させるには、以下のようにします。
\b(contact|email|reach)( us| me)?\b
これにより、contact、contact us、contact me、email、email us、email me、reach、reach us、reach me に一致します。
メールアドレスパターンの検出
一般的なメールアドレスパターンを検出するには、以下のようにします。
\b[\w.%+-]+@[\w.-]+\.[a-zA-Z]{2,}\b
これにより、user@example.com、my.name@sub.domain.co.uk、user+tag@domain.org に一致します。
ハッシュタグのバリエーションの一致
大文字小文字の違いやわずかなバリエーションを持つハッシュタグを一致させるには、以下のようにします。
\#(disc[o0]urse|f[o0]rum)\b
これにより、#discourse、#DISCOURSE、#disc0urse、#forum、#f0rum に一致しますが、#discourseengine や #forums には一致しません。
反復パターンの検出
スパム的なコンテンツを示す可能性のある繰り返し文字を検出するには、以下のようにします。
([a-zA-Z])\1{3,}
これにより、aaaample、helllllo、yessssss に一致し、同じ文字が 4 回以上連続して出現するものを検出します。
プロトコルあり・なしの URL の検索
\b(?:https?:\/\/)?[\w-]+(\.[\w-]+)+\b
これにより、example.com、sub.domain.org、https://discourse.org、http://meta.discourse.org に一致します。
ネストされた文字クラスの回避
正しい例:
(hold)?
これは、オプションの単語 “hold” を正しく一致させます。
または、文字の選択肢を使用する場合:
[h][o0][l1][d]
これにより、hold、h0ld、ho1d、h01d に一致します。
間違った例:
[h[o0][l1]d]?
これは、文字クラスをネストしようとしており、h、o、0、l、1、d のいずれか 1 文字に一致してしまい、had や old などの単語にも誤って一致してしまいます。
オプションの単語に括弧を使用
正しい例:
forum(s)?
これは、forum と forums を正しく一致させます。
間違った例:
forum[s]?
これは、“forum” の後にオプションの “s” が続くものを一致させますが、文字クラスを不必要に使用しています。
正しい文字クラスの使用方法
正しい例:
bad word
これは、フレーズ “bad word” に一致します。
または、文字クラスの例:
[bB][aA][dD]
これにより、bad、Bad、bAd、BAD などに一致します。
間違った例:
[bad word]
これは、b、a、d、w、o、r、d のいずれか 1 文字に一致するだけで、フレーズ “bad word” には一致しません。
量指定子の効果的な使用
\b[0-9]{3,5}\b
これは、3 桁から 5 桁の数字に一致します:123、1234、12345。12 や 123456 には一致しません。
特定の反復パターンに対して:
(spam){2,3}
これにより、spamspam、spamspamspam に一致します。
単語境界の適切な適用
境界なし:
free
これは、free、freedom、carefree に一致します。
境界あり:
\bfree\b
これは、free のみに一致し、freedom や carefree には一致しません。
Unicode 文字の正しい処理
正しいアプローチ:
(?:^|\s)(ö|oe)zel\b
これは、Unicode 文字があっても単語境界で özel、oezel に一致します。
間違ったアプローチ:
\bözel\b
これは、トルコ語の文字 ö では正しく機能しない場合があります。
追加情報
正規表現式は https://regex101.com/ でテストできます。その場合、正規表現のフレーバーを ECMAScript に切り替えることを忘れないでください。
Watched Words の置換値では、正規表現のキャプチャグループのバックリファレンス(例:置換文字列内の \1)はサポートされていません。置換とリンクアクションでは一致に正規表現を使用できますが、置換は常にリテラル文字列となります。