2009-09-29 9 views
5

私が必要とするのは、与えられた文字列が与えられた正規表現と部分的に一致するかどうかを調べることです。たとえば、正規表現ab[0-9]cの場合、文字列 "a"、 "ab"、 "ab3"、および "b3c"は "一致"しますが、文字列 "d"、 "abc"、または "a3c"は一致しません。私がしてきたのは、曖昧なa(?:b(?:[0-9](?:c)?)?)?です(これは、部分的に一致する部分、特に一致する部分でのみ機能します)が、これはAPIの一部であるため、より直観的な一致する正規表現を入力する方法。Javaで部分正規表現マッチを行うためのエレガントな方法はありますか?

説明があまり明確でない場合(これがないかもしれないことがわかっています)、これはテキストボックスのテキスト入力の検証に使用されます。私は、無効な文字列になるすべての編集を防止したいが、完全に入力されるまで、それは一致しないので、正規表現と文字列を一致させることはできません。たとえば、上記の正規表現(ab[0-9]c)を使用して、「a」を入力しようとすると、文字列「a」が正規表現と一致しないため、許可されません。

基本的には、正規表現で動作する逆startsWith()のようなものです。 (new Pattern("ab[0-9]c").startsWith("ab3")trueを返す必要があります)

アイデアはありますか?

+0

FYI: 'a(?:[0-9](?: c)?)?)'?は、 "a"を含む任意の文字列、例えば "jazz " '^ a(?:[0-9](?: c)?)?)?$'を使って文字列全体をマッチングさせたいとします。 – Kip

+0

クライアントが 'ab [0-9] c'のような単純な正規表現を使用していますか、より複雑なマッチング(サブグループとの組み合わせ)が必要でしょうか? – Kip

+0

おっと...ええ、^と$は正規表現に自動的に追加されます。そのため、私はそれらを追加することを忘れてしまいました。ありがとうございます。そして、いいえ、正規表現はそれほど簡単ではありませんが、サブグループを必要とするほどではありませんが、かなり複雑になる可能性があります。 – Tonio

答えて

6

Matcher.hitEnd()は何を探していますか?

Pattern thePattern = Pattern.compile(theRegexString); 
Matcher m = thePattern.matcher(theStringToTest); 
if (m.matches()) { 
    return true; 
} 
return m.hitEnd(); 
+0

ニース!それはほとんど動作します。それは確かに私が現在やっているものの代わりとして働く。部分的なテールマッチ(例えば、 "b3c"は 'ab [0-9] c'の部分一致)にはまだ動作しませんが、私の現在の解決法ではそれらを処理しません。 – Tonio

+0

'hitEnd()'は、正規表現を連続するオプショングループに分割するOP自身の解法と同じ目的を果たします。しかし、まだ部分正規表現の先頭に一致しない部分一致を検出する方法はありません。 –

4

トリッキーがあるかもしれませんが、あなたのやり方はおそらく意味的には最高です。あなたが探しているものを正確に記述します。

しかし、大きな問題は、文字がテキストボックスに入力されるたびに検証する必要があるかどうかです。なぜあなたは一度だけそれを検証して頭痛を救うことができないのですか?ここで

+0

「なぜ」、確かに... :(クライアント(tm)がそれをそう宣言しているので、私がそれをやっているところの問題です。それはかなり不公平です。 APIの奇妙な部分一致正規表現について)、それは正規表現のENDと一致する文字列と一致しないことです。上記の例では、最初に "ab"を付け加えることができるので、 "3c"と一致しません。これは有効である必要があります。 – Tonio

+0

クライアントは本当に正規表現で行わなければならないと指定しましたか?あるいは、設計の特定の部分が技術面から来たのでしょうか? – Yishai

+0

クライアントは正規表現によって行われなければならないと指定しませんでした。これは私たちの設計上の決定でした。もともと単純な文字列のマッチングによって行われていましたが、パターンがかなり複雑になる可能性があるため、最終的に正規表現を使用することにしました。 – Tonio

2

はあなたの特定の例を解決することができます正規表現です:あなたがダウンして、原子の部分に正規表現を破ることができる場合

^(?:a|b|[0-9]|c|ab|b[0-9]|[0-9]c|ab[0-9]|b[0-9]c|ab[0-9]c)?$ 

は、一般的に言って、あなたのことができ、または一緒にそれらのすべての可能なグループ分けが、それは大きいですそして醜い。この場合、4つの部分(a、b、[0-9]、c)があったので、4 + 3 + 2 + 1 = 10の可能性を一緒にORしなければなりませんでした。 (n部分については、(nx(n +1))/ 2可能性)である。これをアルゴリズム的に生成することは可能かもしれませんが、テストするのは巨大な痛みです。そして、複雑なもの(サブグループのようなもの)は正しいものにするのが非常に難しいでしょう。

もっと良い解決策は、入力フィールドの横にメッセージが表示され、ユーザーに「不足している情報」などが表示され、緑色のチェックボックスなどに変更されたときです。ここでは、この問題に対するさまざまなアプローチの長所と短所を比較したA List Apartの最近の記事があります:Inline Validation in Web Forms

+0

これはまさに私が避けようとしていることです...うんざりなregexps(あなたの例ではOR'ed、私の例では最後にオプションのサブグループを含んでいます)。 ( あなたが必要とするのは、不正な文字(有効な文字列にならない違法な意味の文字)の入力をブロックし、完全に有効な文字列を視覚的にフィードバックすることですつまり、文字列が正規表現と完全に一致すると、テキストボックスの背景色が変わります)。 – Tonio

+0

おそらく2つのステップがあります.1つは 'ab [0-9] c'を実行し、完全な文字列あなたが入力したものが有効であるかどうかを知るために大きな正規表現を実行するもの* keyPressedイベントで大きな正規表現を実行でき、失敗した場合はfalseを返します(つまり、その文字) – Kip

+0

これらの正規表現をアルゴリズム的に生成することができれば、それは有効な解決策になります。単純な正規表現のためにそれらを生成することはあまり問題にならないはずですが、使用されているgexpsは単純です。 – Tonio

関連する問題