LoginSignup
17
14

More than 5 years have passed since last update.

ユーザー名を正規表現でチェックする

Last updated at Posted at 2013-05-13

ゲームのユーザー名のチェック処理として適切な正規表現を考えてみる。
結論、これで事足りると思う。

Pattern.compile("[^0-9a-zA-Zぁ-んァ-ヶ一-龠々ー]");

文字の種類

考慮すべき文字種の多すぎてまとめきれる気がしない。

  • 全角ひらがな "あいうえお"
  • 全角カタカナ "アイウエオ"
  • 半角カタカナ "アイウエオ"
  • 全角数字 "12345"
  • 半角数字 "12345"
  • 全角英字大文字 "ABCDE"
  • 全角英字小文字 "abcde"
  • 半角英字大文字 "ABCDE"
  • 半角英字小文字 "abcde"
  • 全角記号 "!#$%&"
  • 半角記号 "!#$%&"
  • 漢字 "亜異兎絵尾"
  • 長音 "ー"
  • 中点 "・"
  • 繰り返し記号 "〃ゝゞヽヾ"
  • 機種依存文字 "①②③④⑤"
  • キリル文字大文字 "АБВГҐ"
  • キリル文字小文字 "абвгґ"
  • ハングル "아가다오쓰"
  • アラビア "غة العرب"

仕様の決め方

UI上の良し悪し(特に視認性)や、ゲームの世界観を判断材料にして決める。

  • 顔文字はNGにしたい (・∀・)
    • 括弧をNGにすればよさそう
  • ユーザー名に句点・読点はなしだと思う
    • じゃあ「モーニング娘。」みたいのもNG?
  • 日本と馴染みの薄い言語の文字はNGにしたい
    • 簡体字・繁体字・ハングル・ロシア・アラビア
    • RMT業者との戦いの歴史があるMMORPGでは特に中国語の印象よくない
  • †聖天使猫姫†みたいな痛ネームは許容すべきか

簡体字と繁体字の除外

日本で使われてる漢字と、簡体字/繁体字は、文字コードのなかでゴチャマゼにないっているため、"一-龠"のような範囲指定では除外不可能。
一般的なゲームでも簡体字/繁体字を除外してるケースは少ないと思われる。
要件的にどうしても除外しなければいけないのなら、簡体字/繁体字テーブルのようなものを作って除外していくしかなさそう。

コード

public class NameChecker {

    private static final String P_STR = "[^0-9a-zA-Zぁ-んァ-ヶ一-龠々ー]"
    private static final Pattern P_NAME = Pattern.compile(P_STR);

    // チェック処理
    public static void check(String name) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0, len = name.length(); i < len; i++) {
            String s = name.substring(i, i + 1);
            if (isMatch(s)) {
                sb.append(s);
            }
        }
        print(name, sb);
    }

    public static boolean isMatch(String s) {
        Matcher matcher = P_NAME.matcher(s);
        return matcher.find();
    }

    private static void print(String name, StringBuilder sb) {
        if (sb.length() == 0) {
            System.out.printf("OK: %s%n", name);
        } else {
            System.out.printf("NG: %d/%d %s [%s]%n", sb.length(), name.length(), name, sb.toString());
        }
    }

    // テストコード
    public static void main(String[] args) {
        long start = System.currentTimeMillis();

        // 半角数字
        check("0123456789");
        // 半角英小文字
        check("abcdefghijklmnopqrstuvwxyz");
        // 半角英大文字
        check("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
        // 全角ひらがな
        check("あいうえお");
        check("かきくけこ");
        check("さしすせそ");
        check("たちつてと");
        check("なにぬねの");
        check("はひふへほ");
        check("まみむめも");
        check("やゆよ");
        check("らりるれろ");
        check("わゐうゑをん");
        check("がぎぐげご");
        check("ざじずぜぞ");
        check("だぢづでど");
        check("ばびぶべぼ");
        check("ぱぴぷぺぽ");
        // 全角ひらがな小文字
        check("ぁぃぅぇぉ");
        check("ゃゅょ");
        // 全角カタカナ
        check("アイウエオ");
        check("カキクケコ");
        check("サシスセソ");
        check("タチツテト");
        check("ナニヌネノ");
        check("ハヒフヘホ");
        check("マミムメモ");
        check("ヤユヨ");
        check("ラリルレロ");
        check("ワヰウヱヲンヴ");
        check("カギグゲゴ");
        check("ザジズゼゾ");
        check("ダヂヅデド");
        check("バビブベボ");
        check("パピプペポ");
        // 全角カタカナ小文字
        check("ァィゥェォ");
        check("ャュョ");
        check("ヶ");
        // 音引き
        check("ー");
        // 漢字
        check("亜々赤白憂鬱幽霊");
        check("嘉緒翠京桜靖ビス湖とっぽ束生夏陽夏照空々");
        check("神生理美依羅炎皇斗幻の銀侍沙利菜愛利江留");
        check("野風平蔵重親愛海月夢杏一将来織田信長");
        check("邪王炎殺黒龍波");
        // 簡体字
        check("北京微梦创科网络技术有限公司");
        check("对写处圆");
        // 繁体字
        check("亞假勛龍龜");
        check("世棒經典賽王建民媽媽嘴大樂透劉真莫那魯道壽司");

        System.out.println("---------- 以下NG ----------");

        // 全角数字
        check("0123456789");
        // 全角英小文字
        check("abcdefghijklmnopqrstuvwxyz");
        // 全角英大文字
        check("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
        // 半角カタカナ
        check("ァィゥェォ");
        check("カキクケコ");
        check("サシスセソ");
        check("タチツテト");
        check("ナニヌネノ");
        check("ハヒフヘホ");
        check("マミムメモ");
        check("ヤユヨ");
        // 中黒
        check("・");
        // 濁音、半濁音
        check("゜゛");
        // 空白
        check("   ");
        // 記号
        check("!#$%&*+,-.:;=?@^_`|~");
        check("!#$%&()*+,.―/ 0-9:;<=>?@A-Z[]^_`a-z{|} ̄");
        check("()[]{}<>");
        check("\"'");
        check("\\");
        check("○△□◇◎●▲■◆");
        check("~~");
        check("--");
        check("♪♫♬");
        check("※〒¶");
        check("…‥。、∴∵,.");
        check("↑→↓←⇐⇒⇔");
        // 繰り返し記号
        check("〃ゝゞヽヾ");
        // 機種依存文字
        check("①②③④⑤⑥⑦⑧⑨⑩");
        // 特殊文字
        check("†聖天使猫姫†");
        // ハングル
        check("아가다오쓰나는");
        // キリル文字
        check("АБВГҐДЃЂЕЄЀЁЖЗЅИІЇЙЍЈКЛЉМНЊОӨПРСТ");
        check("абвгґдѓђеєѐёжзѕиіїйѝјклљмнњоөпрст");
        // アラビア語
        check("غة العربي");

        System.out.println((System.currentTimeMillis() - start) + "ms");
    }
17
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
14