2009-04-16 19 views
26

特定の特殊文字を本質的にブラックにする正規表現を思いつくのに問題があります。特殊文字を除外するための正規表現

これを使用して、入力フィールド(Java Webアプリケーション内)のデータを検証する必要があります。ユーザーは任意の数字、文字(アクセント記号付きの文字、たとえばフランス語またはドイツ語を含む必要があります)と「 - 」などの特殊文字を入力できるようにしたいと考えています。

<>%$などの文字をブラックリストに登録するにはどうすればよいですか?

ご協力いただければ幸いです。

+5

@

/^[a-z0-9]+$/gi 

テスト、それは完全なソリューションが、唯一の提案ではないので、私はコメントでこれをあげますよ。ホワイトリストの文字をブラックリストに載せることよりもはるかに優れています。なぜなら、許可したい文字が拒否するよりはるかに少ないからです。 – JohnFx

+0

ユニコード範囲を使用するための私の更新された回答をチェックしてください。おそらくホワイトリストの問題を単純化するでしょうか? –

+0

ブラックリストモードでは、japanse、chinese、koreanなどが許可されます。これは受け入れられますか? –

答えて

5

許可しないブラックリスト文字ではなく、通常は許可するホワイトリスト文字です。セキュリティの観点からも実装の観点からも容易に実現できます。

ブラックリストルートを終了した場合、ここでは例を示しますが、警告はありますが、構文は単純ではありません。

http://groups.google.com/group/regex/browse_thread/thread/0795c1b958561a07

あなたはおそらく、ユニコード範囲を使用して、すべてのアクセント文字をホワイトリストに登録したい場合に役立つだろうか?このリンクをチェックしてください。

http://www.regular-expressions.info/unicode.html

+0

ご返信ありがとうございます。 最初にホワイトリストを作成しようとしましたが、アクセント付きの文字を許可したいので実用的ではありません。我々はこれで始まった: ^ [a-zA-Z0-9。' - ] + $ その後、すべてのフランス語文字を手動で追加する必要がありました。今私達はすべてのドイツのものなどが必要です。 –

+0

私のパターンを見てください。すべてのアクセント付き文字を含むすべての文字をホワイトリストにします。 – Lucero

+0

Gaijinのリンクによれば、Luceroのパターンはあまりに単純すぎる。 「Unicode Character Properties」というセクションを参照してください。 (すべてのアクセント付き文字を実際に捕まえるには、 "\ p {L} \ p {M} *"のようなものが必要です。)しかし、私はホワイトリストが行く方法だと確信しています。十分に人口を集めたブラックリストが傷つくでしょう。 – BlairHippo

2

あなたは本当に特定の文字をブラックリストというか許可charachtersをホワイトリストに登録しますか?

私はあなたが実際に後者を望んでいると仮定します。これは非常に単純です([\-]グループにホワイトリストに追加の記号を追加):

^(?:\p{L}\p{M}*|[\-])*$ 

編集:私はちょうどホワイトリストの文字だろうコメント

+0

これは正しいアイデアですが、私はキャプチャグループが必要と思わないか、適切な場所にいると思います。 '[ - \ p {L}] *"は、 'matches()'メソッドと一緒に使用しても問題ありませんか? – erickson

+0

はい、そうです。しかし、Java Regexエンジンが[ - \ p {L}]をどのように処理するかはわかりませんでした。私は少なくともキャラクターを逃していただろう。 ^(?:\ p {L} | [\ - ])* $ – Lucero

+0

Gaijinの2つのリンクの2番目のリンクを参照してください。 Unicode Character Properties " - 文字がどのようにエンコードされているかに応じて、必要なものすべてをキャッチしないことがあります。 (そのページは "\ p {L} \ p {M} *"を示唆しています。)しかし、それは解決策に近づいているようにはっきりと感じます。 – BlairHippo

35

からの入力を持つパターンを最適化。

ブラックリストを構築
^[a-zA-Z0-9äöüÄÖÜ]*$ 

正規表現と同様に簡単ですが、あなたがはるかに文字を追加する必要があるかもしれません - 中国のシンボルの多くは、Unicodeである...;)

^[^<>%$]*$ 

表現[ ^(多くの文字はここにあります)]は、リストされていない文字にのみマッチします。

+2

あなたのホワイトリストパターンには、ドイツ語のウムラウトだけが含まれていますが、フランス語やその他の文字はありません。また、多くの共通のものがあります:ñëÿêâôîíìなど。したがって、基本的にUnicode文字グループを使用するだけで、 – Lucero

+1

もちろん...例だけですが、Umlauteはドイツ語のキーボードで入力するのが最も簡単でした。 –

+3

あなたは私が作ろうとしていたことを知りませんでした。これは、サンプルとしてのあなたのキャラクターの選択についてではなく、すべての可能な組み合わせをホワイトリストに入れることが実際にできないことについてです。 – Lucero

4

私はそれがあなたがどの言語をターゲットにしているかによると思います。一般に、このようなものが動作するはずです:

[^<>%$] 

[]」構築物は、列挙された任意の文字と一致します文字クラスを定義します。最初の文字として "^"を置くと、一致が否定されます。

使用している言語/正規表現エンジンに応じて、「[]」内の文字の一部をエスケープする必要があります。

0

許可されている文字と許可されていない文字のリストを思い浮かべるほうがはるかに簡単だろうと思っています。そして、そのリストを取得すると、正規表現の構文はかなり単純になります。だから、「ホワイトリスト」の別の投票として私を置いてください。この正規表現は、それらの中にブラックリストに文字を持っているすべての入力にマッチします

[<>%\$] 

:特定の文字(<、>、%、および$)を除外するには

7

、次のような正規表現を作ることができます。角カッコは文字クラスを定義し、\はドル記号の前に必要です。ドル記号は正規表現で特別な意味を持つからです。

黒いリストにさらに文字を追加するには、角かっこの中に挿入するだけです。注文は関係ありません。あなたは、このための最良のツールはRegex考慮しないのはなぜ

Pattern p = Pattern.compile("[<>%\$]"); 
Matcher m = p.matcher(unsafeInputString); 
if (m.matches()) 
{ 
    // Invalid input: reject it, or remove/change the offending characters. 
} 
else 
{ 
    // Valid input. 
} 
+0

matches()は、正規表現が文字列の両端に '^'と '$'で固定されているかのようにtrueを返します。このアプローチを使用するには、find()を使用する必要があります。しかし、ブラックリストが悪い考えである理由の他の答えを見てください。 –

+0

また、ほとんどのメタキャラクターは、キャラクタークラスに入っているときに特別な意味を失うので、 '$'をエスケープする必要はありません。しかし、あなたがそれをエスケープする必要がある場合は、2つのバックスラッシュ( "\\ $")を使用する必要があります。なぜなら、それはJava Stringリテラル内にあるからです。 –

1

一部Java documentation for regular expressionsによると、あなたはこのように表現を使用することができますか?文字列内に不正な文字が存在するかどうかを検出することを目的としている場合、ループ内の各文字をテストすることは、正規表現を構築するより簡単で効率的です。

+0

HTML入力フィールドのパターン属性は正規表現をとるように設計されているので、同じことをするプログラムを書く理由は何ですか? – Patanjali

1

ここでは、すべてのフランスのアクセント付きの文字があります: àÀâÂäÄáÁéÉèÈêÊëËìÌîÎïÏòÒôÔöÖùÙûÛüÜçÇ'ñ

私はドイツのアクセント付き文字のリストをグーグルます。それほど多くはありません。あなたはそれらをすべて手に入れることができるはずです。私はそうのような通常の文字でアクセント付きのURLを交換したURLの

string beforeConversion = "àÀâÂäÄáÁéÉèÈêÊëËìÌîÎïÏòÒôÔöÖùÙûÛüÜçÇ’ñ"; 
string afterConversion = "aAaAaAaAeEeEeEeEiIiIiIoOoOoOuUuUuUcC'n"; 
for (int i = 0; i < beforeConversion.Length; i++) { 

    cleaned = Regex.Replace(cleaned, beforeConversion[i].ToString(), afterConversion[i].ToString()); 
} 

より効率的な方法は、心はあなたが、おそらくあります。

+0

OPはフランス語とドイツ語のみを例として使用したものであり、徹底的なリストではなく、リストの大きさを示していないことに注意してください。多くの人は、ブラックリストを求めて間違っていると誤解していました。 – Patanjali

3

2009年でさえ、あまりにも多くの人が、世界的なWebのデザインに関わる非常に限定された考えを持っていたようです。 2015年には、特定の国を対象としたデザインをしない限り、ブラックリストが有効な膨大な数の文字を収容する唯一の方法です。

ブラックリストの文字は、データが必要な目的に違反するものに応じて選択する必要があります。

しかし、場合によっては要件を細分化し、それぞれ別々に処理することもあります。ここで先を見てあなたの友人です。これらは正の場合は(?=)、負の場合は(?!)で区切られ、効果的にANDブロックになります。ブロックが処理されたときに失敗しないと、正規表現プロセッサは次のブロックでテキストの先頭から開始します。効果的には、各先読みブロックの前に^があり、そのパターンが欲しい場合は、$までを含めることができます。古くからのVB6/VBA(Office)5.5の正規表現エンジンでも、先読みがサポートされています。

完全正規表現を構築するには、先読みブロックから始めて、最後に$の前にブラックリストの文字ブロックを追加します。

たとえば、3〜15の合計文字数を制限するには、肯定先読みブロック(?=^.{3,15}$)から始めます。すべてのテキストを確実に網羅するためには、^$が必要でした。

ここで、_と - を許可することができますが、開始または終了したくない場合があるので、2つのネガティブルックアヘッドブロックを開始には(?![_-].+)、終了には(?!.+[_-]$)を追加します。

複数の_-が不要な場合は、負の先読みブロック(?!.*[_-]{2,})を追加します。これはまた、_-および-_配列を排除する。 \0-\cZはNL(\n)とCR(\r)を含む、ヌルおよび制御文字を除外

もはや先読みブロックが存在しない場合、そのような[^<>[\]{\}|\\\/^~%# :;,$%?\0-\cZ]+として、$前にブラックリストブロックを追加するには、。最後の+は、すべてのテキストが貪欲に含まれるようにします。

ユニコードドメイン内には、除外する必要がある他のコードポイントやブロックがあるかもしれませんが、確かにホワイトリストに含める必要があるすべてのブロックよりもはるかに少ないです。

上記のすべての全体の正規表現は、あなたがPCRE(PHP)のために、https://regex101.com/に生きてチェックアウトすることができ

(?=^.{3,15}$)(?![_-].+)(?!.+[_-]$)(?!.*[_-]{2,})[^<>[\]{}|\\\/^~%# :;,$%?\0-\cZ]+$ 

、JavaScriptとPythonの正規表現エンジンになります。私はそれらのJava正規表現がどこに合っているのかわかりませんが、あなたは正規表現を修正してその特質を提供する必要があります。

_ではなく空白を含める場合は、正規表現内のすべての場所にスワップしてください。

この技術のために最も有用なアプリケーションは、障害のために偽を返す、単一の式が必要とされるHTML inputフィールド、ためpattern属性のためである、したがって、フィールドが無効になっていinput:invalid CSSはそれをハイライト表示することができ、および停止フォームが提出されます。

+0

正規表現を含む答えを提供するとき、_や*のような一部の文字は、答えのテキストの最終的なレンダリングで消えることに注意してください。その場合は、先に\を付けてください。時々、文字の最初の出現だけが\その文字のすべてが正規表現に表示されるようにする必要があるかもしれません。一貫性がないので、入力時にレンダリングされたテキストを見て、必要に応じて\を追加してください。 – Patanjali

+0

@Mariano。あなたは明らかに私の答えを編集して正規表現を強調表示していますが、明らかに上記のコメントを読んでいないので、各文字の後に文字が表示されるように挿入する必要がありました。あなたの編集は今不要な\ sを左に持っています。私は今それらを編集するでしょう。答えをつぶすつもりなら、完全に編集してください。 @マリアノ。 – Patanjali

+0

。あなたは4つのうちに残しましたが、私は今それを削除しました。 2番目の先読みが間違っているという点で正しいです。私はスタートアップのためにそれを試していたが、その後のことを思い出し、テストなしで特別編集を行った。また、3番目のルックアヘッドの末尾にある '。* 'についても正しく書かれていました。また、始まりについて。ハットトリック! – Patanjali

1

使用この1

^(= [-ZA-Z0-9〜@#$^()_ + = [] {} | \、:。? - ]? $)( ?!。* [<> ' "/;`%])

1

のASCII文字の英数字の&アンダースコアではありませんすべての否定セット:メールアドレスまたはユーザ名の検証のために

/[^\W]/g 

私が使用してきました4つの標準特殊文字 - _。

を許可する次の式厳格な英数字のみの式で使用するために
/^[[email protected]_a-z0-9]+$/gi 

RegExr.com

+0

OPの要件は他の言語を含めることでした。 '\ w'と' \ W'はASCIIのみを扱います。また、範囲内で使用されていない限り、 ' - 'は '[] 'の末尾になければなりません。 – Patanjali

+0

@patanjali /^[[email protected]_a-z0-9]+$/giこれはうまくいきますが、疑いはありません。 – mcgraw

+0

毎日何か新しいことを学んでください: ' - 'は '[]'式の始めか最後に置くことができます。しかし、 '/ [^ \ W] /'は 'á'を処理できませんでした。多言語テキストを実際に扱うには、文字を照合するために '\ p {Ll} \ p {M} *'のような原子表現を使用し、数字を照合するには '\ p {N}'を使わなければなりません。 – Patanjali

関連する問題