• ベストアンサー

正規表現

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]$ _ . - の条件を加えるとうまくいきいません。。 よい方法がございましたらご教授ください!!

質問者が選んだベストアンサー

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.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さんが仰られている通り)。

その他の回答 (4)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

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

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.3

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 とか。

aiyuu_
質問者

お礼

ご解答ありがとうございます。 はい、ほんとは 記述条件@記述条件 という正規表現を作りたかったのですが、 混乱しちゃいそうでしたので記述条件のみの質問にしました。 ^[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]$ の条件と@-_.の連続不可の条件を作るしかないのでしょうか。。

aiyuu_
質問者

補足

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

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

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

aiyuu_
質問者

お礼

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

  • pipipi523
  • ベストアンサー率40% (148/365)
回答No.1

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\.\_\-]$

aiyuu_
質問者

お礼

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

関連するQ&A