1

我需要帮助编写正则表达式以满足以下要求:

  • 以一封信开头
  • 以字母或数字结尾
  • 只有字母、数字、下划线和连字符作为内部字符

以下表达式运行良好,但它允许下划线作为最后一个字符。它应该只允许最后一个字符使用字母或数字:

    ^[A-Za-z][\w-]*\w$
4

4 回答 4

3

使用字符类

您可以为此使用POSIX 字符类。特别是,您可以使用 alphanumeric 类,它是[A-Za-z0-9]. 例如:

^[A-Za-z][\w-]*[[:alnum:]]$
于 2012-07-22T20:08:03.753 回答
2

执行您要求的方法之一是使用负前瞻约束:

^[A-Za-z][\w-]*(?!_)\w$

另一种方法是写出你想要的字符类(Tcl定义\w[[:alnum:]_],即alnum下划线):

^[A-Za-z][\w-]*[[:alnum:]]$

这些接受完全相同的字符串。哪个更好?好吧,唯一可以确定的真正方法是测试(这些时间是在我的旧笔记本电脑上使用较旧的 Tcl 版本;查看相对时间,而不是绝对时间):

% set a "abc123abc123abc123_123"
abc123abc123abc123_123
% set b "abc123abc123abc123123_"
abc123abc123abc123123_
% regexp {^[A-Za-z][\w-]*(?!_)\w$} $a
1
% regexp {^[A-Za-z][\w-]*(?!_)\w$} $b
0
% time {regexp {^[A-Za-z][\w-]*(?!_)\w$} $a} 1000
21.207069999999998 microseconds per iteration
% time {regexp {^[A-Za-z][\w-]*(?!_)\w$} $b} 1000
20.577612000000002 microseconds per iteration
% regexp {^[A-Za-z][\w-]*[[:alnum:]]$} $a
1
% regexp {^[A-Za-z][\w-]*[[:alnum:]]$} $b
0
% time {regexp {^[A-Za-z][\w-]*[[:alnum:]]$} $a} 1000
4.0455700000000006 microseconds per iteration
% time {regexp {^[A-Za-z][\w-]*[[:alnum:]]$} $b} 1000
3.510597 microseconds per iteration

这对我来说看起来很有结论:当你可以编写你真正想要的类时,不要使用前瞻约束。(看起来RE引擎也有未来优化的潜力......)

于 2012-07-22T21:12:38.820 回答
0

您应该使用^[a-zA-Z][-\w]*[a-zA-Z\d]$^[a-zA-Z][-\w]*[^\W_]$

于 2012-07-22T20:00:06.380 回答
-1
^[a-z][a-z0-9_\-]+[a-z0-9]$(?i)
于 2012-07-22T20:01:01.653 回答