Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

一直都在学的正则表达式 #16

Open
damoclesX opened this issue Aug 19, 2015 · 0 comments
Open

一直都在学的正则表达式 #16

damoclesX opened this issue Aug 19, 2015 · 0 comments
Labels

Comments

@damoclesX
Copy link
Owner

damoclesX commented Aug 19, 2015

工作中遇到正则匹配问题,往往都是复制之前的正则表达式,也没有去深究原理。比如电话号码的匹配,邮箱的匹配。另外正则一般情况下也用的比较少,所以导致我都对正则一直都是一知半解,今日工作稍稍空闲,仔细跟着阮一峰前辈的文章,好好学习了下RegExp对象,收获颇丰

解了之前使用中的一些疑惑

  • test的用法
    之前工作中一次偶然机会,遇到了一个问题,关于电话号码匹配。当时出现了一个问题,同一个正则,去匹配一个电话号码,出现了第一次为true,第二次为false。当时真是无语了
var phone = '15228868227';
var reg = /15228868227/g;

console.log(reg.test(phone))
console.log(reg.test(phone))

执行结果是
qq 20150819150909

后面才明白,test时加了g参数,会从上一次匹配成功后的位置开始匹配。可以尝试输入reg的lastIndex

var phone = '15228868227';
var reg = /15228868227/g;
console.log(reg.lastIndex)
console.log(reg.test(phone))
console.log(reg.lastIndex)
console.log(reg.test(phone))

执行结果是
qq 20150819151212
第一次test,是从字符串开始匹配,而第二次时,是从字符串11开始匹配,这时当然什么也匹配不到,返回false

原来如此,看来以后g不能乱加啊,如果g会说话的话,丫的,不懂别乱用我!:)

  • 捕获分组非捕获分组
    捕获性分组和下面几个问题的概念之前就听过,只是没有去深究这到底是个啥,路漫漫其修远兮...

其实很简单,捕获分组,就是加括号

    var str = 'hello world';
    var done = str.replace(/(\w+)\s(\w+)/g,'$2 $1');
    console.log(done)

执行结果

world hello

利用捕获分组,很轻松的将两个单词调换位置

关于$1,$2,可以参考阮一峰前辈的文章,就是捕获到结果的引用

下面也是运用捕获性分组,给每个数字前面加一个中划线

    var str = '9s7xiux786z98aja89sja89aa81jks8s6c6bns4a01';
    var done = str.replace(/(\d)/g,'-$&');
    console.log(done)

加括号是捕获,非捕获性用法(?:),这样就不会捕获匹配的内容

  • 先行断言后行断言
    先行断言和后行断言是指当字符出现或不出现某些字符前时才匹配
    分别是(?=)和(?!),其实比较好记忆,=指是,!指不是
    var str = 'it is enough';
    var done = str.match(/i(?=t)/);
    console.log(done.length)


    str = 'it is enough';
    done = str.match(/i(?!s)/);
    console.log(done.length)

这里便是匹配出现在t前面的i,和匹配不出现在s前的i,虽然这里都有括号,但是先行断言和后行断言不会捕获匹配到的内容

看完这些突然想到以前面试题有个问题是数字千分位,就是111111,转换为111,111的格式

在网上之前看到过这条正则

(''+num).replace(/(\d)(?=(?:\d{3})+$)/g, '$1,');

意思是捕获从末尾开始每隔3个数字的那个数字,并且把它替换成这个数字加一个,

结合了捕获和非捕获、先行断言来解决,我根据理解,写了下面这个正则

    var str = '1231238123123891289128';
    var done = str.replace(/\d(?=(\d{3})+$)/g,'$&,')
    console.log(done)

这里没有像上面那条正则一样,捕获(\d),上面是为了在替换时引用$1,于是捕获,这里其实也可以用$&引用匹配到的内容,能达到同样的效果,只是不清楚捕获分组和非捕获分组哪个效率快,捕获分组有影响的话,正则就要换成

/\d(?=(?:\d{3})+$)/g,'$&,'

这样跟最开始那条正则也相差无几了

路漫漫其修远兮,吾将上下而求索!

@damoclesX damoclesX added the js label Aug 19, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant