dポイントプレゼントキャンペーン実施中!

strutsのバリデータでmaskのみで
以下の条件を正規表現を使ってあらわしたいのですが

使用可能文字
 半角英数字 @ - _ .
条件
 @ _ - . 同一文字の連続使用は不可。
 先頭と最期は半角英数字のみ。
 全部の文字数は3文字以上30文字以内。

aaa@aaa OK
aaa@_-a OK
aaa@@_a NG
a@@@a NG

@マークの連続使用不可は↓でできたのですが、
^[a-zA-Z0-9]([a-zA-Z0-9]+@?){1,30}[a-zA-Z0-9]$

_ . - の条件を加えるとうまくいきいません。。

よい方法がございましたらご教授ください!!

A 回答 (5件)

struts で使えるかどうか分かりませんが、Javaの正規表現の範囲でなら


以下のような手段を講じることでやってやれなくもないです(先読みを使う)。
最後の二つの条件はやっつけなんで、適当に修正してください。

import java.lang.*;
import java.util.regex.*;

class Regtest {
 public static void main(String[] args) {
   Pattern p = Pattern.compile(
     "(?!.*@@)" +      //連続した@を含まない
     "(?!.*__)" +      //連続した_を含まない
     "(?!.*\\.\\.)" +    //連続した.を含まない
     "(?=^.{3,30}$)" +    //3文字以上30文字以下
     "^[a-z].*@.*[a-z]$"   
     );
   String s[] = {"foobar@example", "foobar@@exapmle",
    "abcdefghijklmnopqrstuvwxyzabcdef@hoge",
    "noatmark"};

   for (int i=0; i<s.length; i++) {
     Matcher m = p.matcher(s[i]);
     System.out.print("Test pattern: " + s[i]);
     if (m.find()) {
       System.out.println(" ==> match");
     }
     else {
       System.out.println(" ==> no match");
     }
   }
 }
}

まじめな話をすると、「××でない正規表現」というのは
とっても書きづらいです(#4でTacosanさんが仰られている通り)。
    • good
    • 0

#2 です. ああ, 確かにおかしいや... で終わらせるとしょうがないので, 自信はないけど補足:


1個の正規表現で書くのは, 多分「理論的には可能だけど物理的には不可能」だと思います. DFA で書けるので理論的には正規表現で書けるはずですが, おそらくとんでもない長さになるんじゃないかなぁ? 単純に DFA で書くと分岐点が 28個 (かつ 4~5分岐) だから....
長さの条件を捨てれば (もっと) 簡単に書けるはず... 自信ないけど....
    • good
    • 0

OK/NGの例として挙げられた例を眺めると @ が必須なような気がしますがちがいますか?



それと

^[a-zA-Z0-9]([a-zA-Z0-9]+@?){1,30}[a-zA-Z0-9]$

ですが、{1,30}という量指定子は直前の ([a-zA-Z0-9]+@?)
にかかりますから、文字列の長さとしては全体で
30文字を超える可能性があるのですが本当にうまくいっているのでしょうか?

たとえば

aabcdefghhijkl@mnopqrstuvwxyz@abcdefghik@mnopqrstuvwxyz@z

とか。

この回答への補足

^[a-zA-Z0-9][\w@.-]{1,30}[a-zA-Z0-9]$
ですね。

補足日時:2006/07/18 09:57
    • good
    • 0
この回答へのお礼

ご解答ありがとうございます。
はい、ほんとは

記述条件@記述条件

という正規表現を作りたかったのですが、
混乱しちゃいそうでしたので記述条件のみの質問にしました。

^[a-zA-Z0-9]([a-zA-Z0-9]+@?){1,30}[a-zA-Z0-9]$
については文字列の長さはうまくいってないですね。。+@?をいれているので30文字を超えてしましますね。

^[a-zA-Z0-9][\w.-]{1,30}[a-zA-Z0-9]$
の条件と@-_.の連続不可の条件を作るしかないのでしょうか。。

お礼日時:2006/07/18 09:55

#1 同様私も Struts はわからないので Perl で.


全体の文字数に関する制限を無視すれば,
・先頭と最後は英字
・@, -, ., _ の直後に同じ文字がこない
でよくって, Perl で書けば
/^[a-z]+(@[a-z._-]|\.[a-z@_-]|-[a-z@._]|_[a-z@.-]|[a-z]+)*$/
だけなんですが....
文字数については, 無理に正規表現で書く必要はないと思う. ま, わけていいなら
/^[a-z@._-]{3,30}$/ && ! /@@/ && ! /--/ && ! /\.\./ && ! /__/
が最も理解しやすい気もするけど.
    • good
    • 0
この回答へのお礼

ご解答ありがとうございます。
/^[a-z]+(@[a-z._-]|\.[a-z@_-]|-[a-z@._]|_[a-z@.-]|[a-z]+)*$/
ですが、
a@.
a@--d
もtrueになってしまいます。
私もstrutsほとんどわからないので
validator.xmlに
/^[a-z@._-]{3,30}$/ && ! /@@/ && ! /--/ && ! /\.\./ && ! /__/
の様に複数の条件を記述できるのかな。。

お礼日時:2006/07/18 09:50

Strutsは使ったことがないのですが・・・


perlだとこれでOKになってます
$_='aaa@b.-_';
print "OK\n" if(/^[a-zA-Z0-9._-]([a-zA-Z0-9._-]+@?){1,30}[a-zA-Z0-9._-]$/);

こんな感じにメタキャラをエスケープしてみるとかでは?
^[a-zA-Z0-9\.\_\-]$
    • good
    • 0
この回答へのお礼

ご解答ありがとうございます。
メタキャラをエスケープしても、@以外の文字が連続使用可能でした。。

お礼日時:2006/07/18 09:44

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!