关于正则

概念:

正则表达式(Regular Expression)是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。

通俗来讲:正则表达式是用来处理字符串的,可以用一些特定字符来描述字符串里字符出现的规则,从而匹配,提取或者替换符合某一个规则的字符串。比如(像文章关键字替换,密码,手机等认证,邮箱等,都要用到正则)

创建:

  • 第一种:构造函数
    var reg = new RegExp('hi','g')
  • 第二种:字面量
    var reg = /hi/g

修饰符:

1.g:global,全文搜索,不添加的话搜索到第一个结果停止搜索
2.i:ingore case,忽略大小写,默认大小写敏感
3.m:multiple lines,多行搜索
下面列子理解下g,i,m的作用; 
QQ截图20161221221757.jpg
QQ截图20161221224544.jpg

正则常用的两种方法:

test方法:test() 方法检索字符串中的指定值。返回值是 true 或 false。

var str = "my name is zyn"
var reg = /name/
console.log(reg.test(str); //ture

exec方法:exec() 方法检索字符串中的指定值。返回值是被找到的值。如果没有发现匹配,则返回 null。

var str = "my name is zyn"
var reg = /name/
console.log(reg.exec(str); //name

字符类

我们可以使用元字符[]来构建一个简单的类,所谓类是指,符合某些特征的对象,是一个泛指,而不是特指某个字符了,我们可以使用表达式 [abc]把字符a或b或c归为一类,表达式可以匹配这类的字符(如)
var str = "abcdefacbsq";
var reg =/[abc]/g;
console.log(str.match(reg));//["a", "b", "c", "a", "c", "b"]

var reg1 =/[a-e]/g;
console.log(str.match(reg1));//["a", "b", "c", "d", "e", "a", "c", "b"]

取反

元字符[]组合可以创建一个类,我们还可以使用元字符^创建反向类/负向类,反向类的意思是不属于XXX类的内容,表达式 [^abc] 表示不是字符a或b或c的内容(如)
var str = "abcdefacbsq";
var reg =/[^abc]/g;
console.log(str.match(reg));//["d", "e", "f", "s", "q"]

var reg1 =/[^a-e]/g;
console.log(str.match(reg1));//["f", "s", "q"]

元字符

正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符
如(( [ { \ ^ $ | ) ? * + .)后面会讲到

并不是每个元字符都有特定的意义,在不同的组合中元字符有不同的意义,分类看一下

字符 含义
\t 水平制表符
\r 回车符
\n 换行符
\f 换页符
\cX 与X对应的控制字符Ctrl+X
\v 垂直制表符
\0 空字符

预定义类

字符 字符 含义
. [^\r\n] 除了回车符和换行符之外的所有字符
\d [0-9] 数字字符
\D [^0-9] 非数字字符
\s [\t\n\x0B\f\r] 空白符
\S [^\t\n\x0B\f\r] 非空白符
\w [a-zA-Z_0-9] 单词字符,字母,数字下划线
\W [^a-zA-Z_0-9] 非单词字符

边界

字符 含义
^ 以xxx开头
$ 以xxx结尾
\b 单词边界
\B 非单词边界

量词

字符 含义
出现零次或一次(最多出现一次)
+ 出现一次或多次(至少出现一次)
* 出现零次或多次(任意次)
{n} 出现n次
{n,m} 出现n到m次
{n,} 至少出现n次
{,m} 最多出现m次

贪婪模式与非贪婪模式

贪婪模式:量词在默认下是尽可能多的匹配的;
非贪婪模式:让正则表达式尽可能少的匹配,也就是说一旦成功匹配不再继续尝试,做法很简单,在量词后加上?
简单来说JS中的正则表达式的贪婪模式和非贪婪模式主要是匹配方式上有所不同(如)
var  str = "how  ! old are  you! I am !30! year"
var reg =/!.+!/
console.log(str.match(reg) );//["! old are  you! I am !30!"]
我们想要的是["! old are you!",!30!]可是为什么得到这个结果?
这是正则表达式的匹配方式导致的。
正则表达式默认的匹配的方式就是贪婪模式。
  • 贪婪模式:

1 首先在"how ! old are you! I am !30! year"
这个字符串中,使用/!.+!/进行匹配,那么这个正则式首先寻找的是一个感叹号! 如下图:

QQ截图20161222001216.jpg

2 于是/!.+!/正则就会开始匹配.,而 . 这个符号可以匹配除换行符外的全部字符,于是它就一直匹配到了最后,直到文本结束:

QQ截图20161222001330.jpg

3 .号匹配完毕后,开始匹配后面的!,于是正则/!.+!/开始往回匹配感叹号!,一直匹配到30后面的!,发现符合规则了,于是匹配出来的就是这一串字符串

QQ截图20161222001722.jpg
所以会有以上的输出,那怎么得到我们要的结果呢?
改为费贪婪模式:reg =/!.+?!/
var  str = "how  ! old are  you! I am !30! year"
var reg =/!.+?!/g
console.log(str.match(reg) );//["! old are  you!", "!30!"]

  • 非贪婪模式:

1 首先在"how ! old are you! I am !30! year"
这个字符串中,使用/!.+!/进行匹配,那么这个正则式首先寻找的是一个感叹号! 如下图:

QQ截图20161222001216.jpg

2 然后进行 . 的匹配,但是与贪婪模式不同的是,它每匹配一次.
,就会往后匹配一次!,于是就出现了如下图的结果:

QQ截图20161222002227.jpg

3 因为g是全局匹配,所以该正则又会从头开始匹配第一个!,到了!30后,匹配成功第一个!和两个.,以及后面的!,于是!30!也被匹配上了,然后该正则又剩下的字符串开始从新匹配,而后面因为不能匹配出第一个!,于是就没有匹配出来:

QQ截图20161222002554.jpg

下面做一些练习题

1. \d,\w,\s,[a-zA-Z0-9],\b,.,*,+,?,x{3},^$分别是什么?

\d:数字字符;
\w:单词字符,字母,数字下划线;
[a-zA-Z0-9]:取字母a到z任意字母的大小写,和任意数字0到9;
\b:单词边界;
.:除了回车符和换行符之外的所有字符;
+:出现一次或者多次;
?:出现0次或者一次;
x{3}:x出现3次;
^$:^:表示匹配任何开头为输出值的字符串,$:表示匹配任何结尾为输出值的字符串,两者结合就是一个空字符;

2. 贪婪模式和非贪婪模式指什么?

贪婪模式和非贪婪模式,或者说匹配优先和忽略优先。标准量词修饰的子表达式,在可匹配可不匹配的情况下,总会先尝试进行匹配,称贪婪模式,例如{n}、{m,n}、*、+、. 。
而非贪婪模式就是在可匹配可不匹配的情况下,总会优先忽略匹配,直到必须匹配才能使表达式匹配成功时,才会进行匹配。只要在标准量词后加?即进入非贪婪模式。例如{n}?、*?、??、+?。

3. 写一个函数trim(str),去除字符串两边的空白字符

function trim(str){
    return str.replace(/(^\s+)|(\s+$)/g,"");    
}
console.log(trim('ab c'));//ab c
console.log(trim('ab c '));//ab c
console.log(trim(' ab c'));//ab c
console.log(trim(' abc '));//abc
console.log(trim('  abc   '));//abc
console.log(trim(' a b c '));//a b c

4. 使用实现 addClass(el, cls) hasClass(el, cls) removeClass(el,cls)使用正则

var test = document.getElementById('test')
function hasClass(el, cls) {
    //左边是开头或者空格,右边是结尾或者空格
    var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)', 'g');
  // var reg = new RegExp('(\s|^)' + cls + '(\s|$)', 'g');
    return reg.test(el.className);
}


function addClass(el, cls) {
    var reg = new RegExp('(\\s|^)' + cls + '(\s|$)', 'g');

    if (!reg.test(el.className)) {
        el.className = el.className + ' ' + cls;
    }
}

function removeClass(el, cls) {
    var reg = new RegExp('(\\s|^)' + cls + '(\s|$)', 'g');

    //先替换成空格 再去掉多余的空格
    if (reg.test(el.className)) {
        el.className = el.className.replace(reg, ' ').replace(/\s{2,}/g, ' ');
    }
}

5. 写一个函数isEmail(str),判断用户输入的是不是邮箱

function isEmail(str){

    var reg = /(\S)+[@]{1}(\S)+[.]{1}(\w)+/
    return reg.test(str);
}

6. 写一个函数isPhoneNum(str),判断用户输入的是不是手机号

function isPhone(str){

    var reg = /^1[3-9]{10}$/;
    return reg.test(str);

}

7 .写一个函数isValidUsername(str),判断用户输入的是不是合法的用户名(长度6-20个字符,只能包括字母、数字、下划线)

function isValidUsername(str){

    var reg = /\w{6,20}$/
    return reg.test(str)
}

8 .写一个函数isValidPassword(str),判断用户输入的是不是合法密码(长度6-20个字符,包括大写字母、小写字母、数字、下划线至少包括两种)


function isValidPassword(str){

    if(str.length<6 || str.length>20){

        return false;
    }//长度条件

    if(/[^\w]/g.test(str))
    {
        return false;
    }//其他字符;

    if(/(^[a-z]+$)|(^[A-Z]+$)|(^\d+$)|(^_+$)/g.test(str)){

         return fasle;
    }//只有一种值得情况
    return true;

}

9. 写一个正则表达式,得到如下字符串里所有的颜色

var re = /*正则...*/
var subj = "color: #121212; background-color: #AA00ef; width: 12px; bad-colors: f#fddee #fd2 "
alert( subj.match(re) )
var reg = /#[A-Fa-f0-9]+/g;
var subj = "color: #121212; background-color: #AA00ef; width: 12px; bad-colors: f#fddee #fd2 ";
console.log(subj.match(reg));//["#121212", "#AA00ef", "#fddee", "#fd2"]

10.下面代码输出什么? 为什么? 改写代码,让其输出hunger, world.

var str = 'hello "hunger" , hello "world"';
var pat = /".*"/g;str.match(pat);
 // 输出结果是:"hunger" , hello "world",原因是因为.*使这个正则表达式处于贪婪模式,所以在hunger前面有一个",而world的后面也有一个",并且中间的所有字符都可以匹配.这个符号,所以第一个双引号和最后一个双引号之间的字符全部都匹配上了;
var str = 'hello  "hunger" , hello "world"';
var pat =  /".*?"/g;
console.log(str.match(pat));//[""hunger"", ""world""]
//改写成了非贪婪模式;

11.补全如下正则表达式,输出字符串中的注释内容. (可尝试使用贪婪模式和非贪婪模式两种方法)

str = '.. <!-- My -- comment \n test --> .. <!----> .. '
re = /.. your regexp ../str.match(re) // '<!-- My -- comment \n test -->', '<!---->'
非贪婪模式

str = '.. <!-- My -- comment \n test --> ..  <!----> .. '
re = /<!--[\w\W]*?-->/g;

console.log(str.match(re)); // '<!-- My -- comment \n test -->', '<!---->'


str = '.. <!-- My -- comment \n test --> ..  <!----> .. ';
re = /<[^\r]*?>/g;
console.log(str.match(re)); // '<!-- My -- comment \n test -->', '<!---->'
贪婪模式
str = '.. <!-- My -- comment \n test --> ..  <!----> .. '
re = /<!--[^>]*-->/g;
console.log(str.match(re)); // '<!-- My -- comment \n test -->', '<!---->'


str = '.. <!-- My -- comment \n test --> ..  <!----> .. ';
re = /[^.]*>/g;
console.log(str.match(re)); // '<!-- My -- comment \n test -->', '<!---->'

12. 补全如下正则表达式

var re = /* your regexp */
var str = '<> <a href="/"> <input type="radio" checked> <b>'
str.match(re) // '<a href="/">', '<input type="radio" checked>', '<b>'
var re = /<[a-z].*?>/g
var str = '<> <a href="/"> <input type="radio" checked> <b>'
console.log(str.match(re))
//["<a href="/">", "<input type="radio" checked>", "<b>"]
//非贪婪模式


var re = /<[^>]+>/g;
var str = '<> <a href="/"> <input type="radio" checked> <b>';
console.log(str.match(re));
 // '<a href="/">', '<input type="radio" checked>', '<b>'
//贪婪模式

版权归饥人谷--楠柒所有 如有转载请标明出处

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容

  • --------------------------正则的作用--------------------------...
    G_whk阅读 613评论 1 5
  • 初衷:看了很多视频、文章,最后却通通忘记了,别人的知识依旧是别人的,自己却什么都没获得。此系列文章旨在加深自己的印...
    DCbryant阅读 3,995评论 0 20
  • 转自: JS正则表达式一条龙讲解,从原理和语法到JS正则、ES6正则扩展,最后再到正则实践思路 温馨提示:文章很长...
    前端渣渣阅读 1,803评论 1 32
  • 正则表达式指符合一定规则的表达式,专门用于操作字符串。用一些特定的符号来表示一些代码操作,以此来简化书写。只需要书...
    李斯维阅读 749评论 1 11
  • 好尴尬
    昨天比较不爱你阅读 238评论 0 0