正则表达式 - 没有下划线作为最后一个字符

时间:2012-07-22 19:57:31

标签: regex tcl expect

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

  • 以字母开头
  • 以字母或数字结尾
  • 内部字符只有字母,数字,下划线和连字符

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

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

4 个答案:

答案 0 :(得分:3)

使用字符类

您可以使用POSIX character class。特别是,您可以使用字母数字类,它是[A-Za-z0-9]的简写。例如:

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

答案 1 :(得分: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引擎的未来优化也有可能......)

答案 2 :(得分:0)

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

答案 3 :(得分:-1)

^[a-z][a-z0-9_\-]+[a-z0-9]$(?i)