将Regex更改为仅接受指定的字符?

时间:2011-12-15 22:14:33

标签: javascript regex

我目前在javascript文件中有正则表达式:

function (value) {
    regex = new RegExp("[\<|\>|\"|\'|\%|\;|\(|\)|\&|\_|\.]", "i");
    return !regex.test(value);
}

我如何说明允许使用哪些字符,而不是指定哪些字符不被允许?我想要的字符是a-z A-Z 0-9(以及实际字符“ - ”但不在开头或结尾,仅在中间)。谢谢你提前。

3 个答案:

答案 0 :(得分:3)

regex = new RegExp("^[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*$");

再次经典的“正常*(特殊法线*)*”模式;)

功能体变为:

function (value) {
    regex = new RegExp("^[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*$");
    return regex.test(value) && value.length >= 6;
}

编辑:由于没有在此处进行捕获,因此将分组设为非捕获

答案 1 :(得分:1)

在开头或结尾没有破折号的限制使正则表达式更复杂一些。下面的正则表达式首先匹配单个字符,然后它可选地匹配零个或多个字符,包括破折号,然后以非短划线字符结束。

/^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$/

答案 2 :(得分:1)

试试这个

regex = new RegExp("^(?!-)[a-z0-9-]*[a-z0-9]$", "i");

^锚定到字符串的开头

(?!-)向前看是负面的,确保字符串不以破折号开头

[a-z0-9-]*类中的0个或更多个字符

[a-z0-9]$以类

中的字符结尾

请参阅此regex here on Regexr

<强>更新

这是使用两个前瞻的变体,这也会接受空字符串

^(?!-)(?!.*-$)[a-z0-9-]*$

See it on Regexr

更新2:最少6个字符

^(?!-)[a-z0-9-]{5,}[a-z0-9]$

See it on Regexr

反驳评论

  

实际上它太复杂了一个正则表达式 - 而且肯定比它慢   我的正则表达式

我做了一个小基准测试(在Perl中,应该不是什么大问题)

sub WithLookahead($) {
    my $string = shift;

    return $string =~ /^(?!-)[a-z0-9-]*[a-z0-9]$/i;
}

sub WithOutLookahead($) {
    my $string = shift;

    return ( $string =~ /^[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*$/
          && length($string) >= 6 );
}

sub BenchmarkLookahead($) {
    use Benchmark;
    my $testString = shift;

    my $t0 = Benchmark->new;
    for ( 0 .. 10000000 ) {
        my $result = WithLookahead($testString);
    }
    my $t1 = Benchmark->new;

    my $t2 = Benchmark->new;
    for ( 0 .. 10000000 ) {
        my $result = WithOutLookahead($testString);
    }
    my $t3 = Benchmark->new;

    my $tdWith    = timediff( $t1, $t0 );
    my $tdWithOut = timediff( $t3, $t2 );
    print "the code with Lookahead and test string \"$testString\" took:",    timestr($tdWith),    "\n";
    print "the code without Lookahead and test string \"$testString\" took:", timestr($tdWithOut), "\n";
}

<强>结果

  

使用Lookahead和测试字符串“Foo-Bar”的代码:16个挂钟秒(14.94 usr + 0.00 sys = 14.94 CPU)
  没有Lookahead的代码和测试字符串“Foo-Bar”采用:18个wallclock secs(17.50 usr + 0.02 sys = 17.52 CPU)
  使用Lookahead和测试字符串“-Foo-Bar”的代码:13个wallclock secs(12.03 usr + 0.00 sys = 12.03 CPU)
  没有Lookahead的代码和测试字符串“-Foo-Bar”采用:14个wallclock secs(13.44 usr + 0.00 sys = 13.44 CPU)
  带有Lookahead和测试字符串“Foo-Bar-”的代码:17个wallclock secs(15.28 usr + 0.00 sys = 15.28 CPU)
  没有Lookahead的代码和测试字符串“Foo-Bar-”采用:23个wallclock secs(21.61 usr + 0.02 sys = 21.63 CPU)
  使用Lookahead和测试字符串“Foo”的代码:14个wallclock secs(13.70 usr + 0.00 sys = 13.70 CPU)
  没有Lookahead和测试字符串“Foo”的代码占用了:19个挂钟秒(17.09 usr + 0.02 sys = 17.11 CPU)

总的来说,使用负向前瞻的正则表达式比将更简单的正则表达式与外部长度检查相结合要快一些。但我需要将每个代码调用10000000次以获得显着的结果,因此我认为它不是一个性能决定使用哪个。