首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否将正则表达式更改为只接受指定的字符?

是否将正则表达式更改为只接受指定的字符?
EN

Stack Overflow用户
提问于 2011-12-16 06:14:33
回答 3查看 291关注 0票数 0

我目前有一个javascript文件中的regex,如下所示:

代码语言:javascript
复制
function (value) {
    regex = new RegExp("[\<|\>|\"|\'|\%|\;|\(|\)|\&|\_|\.]", "i");
    return !regex.test(value);
}

我不是指定哪些字符是不允许的,而是如何说明哪些字符是允许的?我想要的字符是a-z A-Z 0-9 (还有实际的字符"-“,但不在开头或结尾,只在中间)。在进阶时谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-12-16 06:19:29

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

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

函数体变成:

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

编辑:分组不捕获,因为这里没有捕获

票数 3
EN

Stack Overflow用户

发布于 2011-12-16 06:19:21

在开头或结尾不使用破折号的限制使正则表达式变得稍微复杂一些。下面的正则表达式首先匹配单个字符,然后可选地匹配包括破折号在内的零个或多个字符,最后以非破折号字符结尾。

代码语言:javascript
复制
/^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$/
票数 1
EN

Stack Overflow用户

发布于 2011-12-16 06:22:14

尝尝这个

代码语言:javascript
复制
regex = new RegExp("^(?!-)[a-z0-9-]*[a-z0-9]$", "i");

^锚定到字符串的开头

(?!-)负前视确保字符串不以破折号开头

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

[a-z0-9]$以类中的字符结尾

查看此regex here on Regexr

更新

这是一个使用两个lookahead的变体,它也将接受空字符串

代码语言:javascript
复制
^(?!-)(?!.*-$)[a-z0-9-]*$

See it on Regexr

更新2:最少6个字符的

代码语言:javascript
复制
^(?!-)[a-z0-9-]{5,}[a-z0-9]$

See it on Regexr

反驳评论

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

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

代码语言:javascript
复制
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-

”测试代码:16秒(14.94usr+0.00sys=14.94cpu)

没有Lookahead和测试字符串"Foo-Bar“的代码耗时:18秒(17.50usr+0.02sys=17.52cpu)

具有Lookahead和测试字符串"-Foo-Bar“的代码所用时间:13秒(12.03 usr +0.00sys= 12.03 CPU)

不带Lookahead和测试字符串"-Foo-Bar“的代码耗时14秒(13.44usr+0.00sys=13.44CPU)

使用Lookahead和测试字符串"Foo-Bar-“的代码:17秒(15.28 usr +0.00sys= 15.28 CPU)

不使用Lookahead和测试字符串"Foo-Bar-“的代码:23秒(21.61usr+0.02sys=21.63CPU)

具有Lookahead和测试字符串"Foo“的代码所用时间:14秒(13.70 usr +0.00sys= 13.70 CPU)

不带Lookahead和测试字符串"Foo“的代码耗时19秒(17.09usr+0.02sys=17.11cpu)

因此,总的来说,我的带有负先行的正则表达式比更简单的正则表达式和外部长度检查的组合要快一点。但我需要调用每个代码10000000次才能获得显着的结果,所以我不认为这是性能决定使用哪一个。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8527375

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档