1

我正在寻找一个正则表达式来验证用户名。

用户名可能包含:

  • 字母(西方、希腊、俄罗斯等)
  • 数字
  • 空格,但一次只有 1 个
  • 特殊字符(例如:)"!@#$%^&*.:;<>?/\|{}[]_+=-",但一次只有 1 个

编辑:

对困惑感到抱歉

  • 我需要它用于可可触摸,但无论如何我都必须将它翻译为服务器端的 php。
  • 一次 1 我的意思是空格或特殊字符应该用字母或数字分隔。
4

5 回答 5

8

与其编写一个大的正则表达式,不如编写单独的正则表达式来测试您想要的每个条件会更清楚。

  • 测试用户名是否仅包含字母、数字、ASCII 符号!@和空格:^(\p{L}|\p{N}|[!-@]| )+$。这必须匹配用户名才有效。注意\p{L}Unicode 字母\p{N}类和 Unicode 数字类的使用。

  • 测试用户名是否包含连续空格:\s\s+. 如果匹配,则用户名无效。

  • 测试符号是否连续出现:[!-@][!-@]+. 如果匹配,则用户名无效。

这完全符合您所写的标准。

但是,根据用户名的编写方式,这种方法可能仍会拒绝完全有效的名称,例如“Éponine”。这是因为“É”可以写成 U+00C9 LATIN CAPITAL E WITH ACUTE(由 匹配\p{L})或E后跟 U+02CA MODIFIER LETTER ACUTE ACCENT(匹配\p{L}。)

Regular-Expressions.info 说得更好

同样,“字符”实际上意味着“Unicode 代码点”。\p{L} 匹配“字母”类别中的单个代码点。如果您的输入字符串 à 编码为 U+0061 U+0300,则它匹配没有重音符号的 a。如果输入是 à 编码为 U+00E0,它匹配 à 和重音。原因是代码点 U+0061 (a) 和 U+00E0 (à) 都属于“字母”类别,而 U+0300 属于“标记”类别。

Unicode 很麻烦,无论如何限制用户名中的字符也不一定是个好主意。你确定你要这么做吗?

于 2012-04-24T14:52:12.457 回答
1

表达方式

^(\w| (?! )|["!@#$%^&*.:;<>?/\|{}\[\]_+=\-")](?!["!@#$%^&*.:;<>?/\|{}\[\]_+=\-")]))*$

如果您的方言支持前瞻断言,它将主要做您想做的事情。在RegExr中查看它的实际应用。

请问问自己为什么要以这种方式限制用户名。大多数时候用户名以“!!”开头 应该不是问题,如果您拒绝用户想要的用户名,您会惹恼用户。

编辑: \w不匹配非拉丁字符。为此,根据您的正则表达式实现,替换\w为wich 可能有效,也可能无效。\p{L}不幸的是,Regexr 不支持它。

于 2012-04-24T13:33:38.333 回答
1

试试这个:

^[!@#$%^&*.:;<>?\/\|{}\[\]_+= -]?([\p{L}\d]+[!@#$%^&*.:;<>?/\|{}\[\]_+= -]?)+$

红字

于 2012-04-24T13:35:14.000 回答
0

你想要类似的东西

string strUserName = "BillYBob Stev#nS0&";
Regex regex = new Regex(@"(?i)\b(\w+\p{P}*\p{S}*\p{Z}*\p{C}*\s?)+\b");
Match match = regex.Match(strUserName);

如果你想要这个解释,请告诉我。

我希望这有帮助。

注意:这是不区分大小写的。

于 2012-04-24T13:38:27.533 回答
0

由于我不知道您需要哪种语言的解决方案,因此我使用 Java 提供答案。它可以在任何其他平台上翻译:

String str = "à123 àà@bcà#";
String regex = "^([\\p{L}\\d]+[!@#$%\\^&\\*.:;<>\\?/\\|{}\\[\\]_\\+=\\s-]?)+$";
Pattern p = Pattern.compile(regex);
matcher = p.matcher(str);
if (matcher.find())
   System.out.println("Matched: " + matcher.group());

我做出的一个假设是用户名将以 unicode 字母或数字开头。

于 2012-04-24T13:47:28.440 回答