loading...

0

常用正则整理

正则读完大概需要23分钟

  • 发布时间:2019-04-08 10:07 星期一
  • 刘伟波
  • 939
  • 更新于2019-06-26 19:07 星期三

正则预测

^ 匹配一行的开头位置

(?![0-9]+$) 预测该位置后面不全是数字

(?![a-zA-Z]+$) 预测该位置后面不全是字母

[0-9A-Za-z] {6,10} 由6-10位数字或这字母组成

$ 匹配行结尾位置

$pattern = '/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,10}$/';

    var reg=/(\d{3})\d{4}(\d{4})/;

    var phone="13423874592";

   console.log( phone.replace(reg,("$1****$2")));//134****4592

    var reg=/w.rar|zip|gz/;

    var file="test.rar";

    console.log(reg.test(file));

    var reg=/^[a-zA-Z_0-9.-] @[a-zA-Z_0-9.-] .[a-zA-Z] $/;

    var email="xiaoming.he-he@163.com";

    console.log(reg.test(email));

字符串不确定空格分割js

   1.var str="fdsfsdf dfsf dfsf    dsfasf";

    console.log(str.split(/[  ]+ /))
    console.log(str.split(/\s+ /))

   2.var str="aaa_big.img";
   console.log(str.replace(/_big/,""));//aaa.img

正则添加变量

http://blog.csdn.net/icanlove/article/details/39499777

var v = "bl";

var re =new RegExp("^\\d+" + v + "$","gim"); // re为/^\d+bl$/gim

//至此,最初的问题问题也完全解决了。

//另外,还有一种方法是用过eval动态执行一段字符串的方法,不过我觉得从各方面来说,都属下策。

var re = eval("/^\\d+" + v + "$/gim")

正则查找字符串

let reg=new RegExp("project","g");
let str=http://localhost:63342/project/test.html?_ijt=7eg35ek3pq5s7f4dgecpc89n4h;

console.log(reg.test(str));

var str = 'abcdef';
var re = /B/i;
//var re = new RegExp('B','i'); 也可以这样写
alert( str.search(re) ); // 1

match() 在字符串中搜索复合规则的内容,搜索成功就返回内容,格式为数组,失败就返回null。

  • 用法: 字符串.match(正则)

  • 量词: 至少出现一次 匹配不确定的次数(匹配就是搜索查找的意思)

  • 全局匹配:g——global(正则中默认,只要搜索到复合规则的内容就会结束搜索 )

例子:找出指定格式的所有数字,如下找到 123,54,33,879

var str = 'haj123sdk54hask33dkhalsd879';

var re = /\d+/g;// 每次匹配至少一个数字 且全局匹配 如果不是全局匹配,当找到数字123,它就会停止了。就只会弹出123.加上全局匹配,就会从开始到结束一直去搜索符合规则的。如果没有加号,匹配的结果就是1,2,3,5,4,3,3,879并不是我们想要的,有了加号,每次匹配的数字就是至少一个了

alert( str.match(re) ); // [123,54,33,879]

replace() :查找符合正则的字符串,就替换成对应的字符串。返回替换后的内容。

用法: 字符串.replace(正则,新的字符串/回调函数)(在回调函数中,第一个参数指的是每次匹配成功的字符)

| : 或的意思 。

例子:敏感词过滤,比如 我爱北京天安门,天安门上太阳升。------我爱****上太阳升。即北京和天安门变成号,

一开始我们可能会想到这样的方法:

var str = "我爱北京天安门,天安门上太阳升。";
var re = /北京|天安门/g; // 找到北京 或者天安门 全局匹配
var str2 = str.replace(re,'*');
alert(str2) //我爱**,*上太阳升
//这种只是把找到的变成了一个*,并不能几个字就对应几个*。

要想实现几个字对应几个*,我们可以用回调函数实现:

var str = "我爱北京天安门,天安门上太阳升。";
var re = /北京|天安门/g; // 找到北京 或者天安门 全局匹配
var str2 = str.replace(re,function(str){
alert(str); //用来测试:函数的第一个参数代表每次搜索到的符合正则的字符,所以第一次str指的是北京 第二次str是天安门 第三次str是天安门
var result = '';
for(var i=0;i<str.length;i  ){
result  = '*';
}
return result; //所以搜索到了几个字就返回几个*
});
alert(str2) //我爱*****,***上太阳升

//整个过程就是,找到北京,替换成了两个,找到天安门替换成了3个,找到天安门替换成3个*。

var arr = {
    content: "你好#D12345#,hello#D321#world",
    lawitems: {
        "D12345": "aaaa",
        "D321": "bbbbb"
    }
}

arr.content = arr.content.replace(/#([^#] )#/g, function (match, $1) {
    return arr.lawitems[$1]||match;//没有在lawitems找到返回原字符串
})

replace是一个很有用的方法,经常会用到。

边界类

 边界类主要用四个: ^ 表示以什么开始,$表示以什么结尾, , boudary 表示单词边界,B 表示非单词边界。边界就是单词和单词相隔的地方,最明显的就是空格。

写一个例子来看一下可以更为直观。

let reg = /is/g;
let string = 'this is a dog '
let replaceString = string.replace(reg,"IS");
console.log(replaceString)  // thIS IS a dog

  两个is 都被替换掉了,这符合预期。但我们怎么只替换中间的is,中间的is 有一个特点,它是一个单词,因为前面和后面都是空格,使得它与其它单词分开了,正因为有空格的存在is 才成为了一个单词,所以空格是单词边界, \b 可以匹配到它。把正则表达式改成 /\bis/g, 可以看到输出 this IS a dog, 只匹配第二个。 如果只想改变第一个呢?那好办,因为第一个is被包含在一个单词中,所以它的前面不是单词边界,直接改成B 就可以了, 正则表达式改成 /Bis/g 就可以了.

^$ 很好理解, /^T/以大写字母T开头即可, /T$/ 以大写字母T结束即可, 要注意它们的书写位置,一个在前,一个在后. 如果字符串中有换行符,let string = '@123 @456 @789', 字符串表现地就像有三行一样. 以下是chrome 浏览器中的输出

这时如果以/^@/g 去进行匹配的话,它只会匹配第一个@,


let reg = /^@/g;
let string = '@123
@456
@789'
let replaceString = string.replace(reg,"X");
console.log(replaceString)
/*
*    X123
*    @456
*    @789
*/

如果想匹配三个,那就要用到m修饰符,多行标示符,它表示如果字符串中有换行符,那就把字符串当成多行看待。m标示符,只有在正则表达式中有^或&时才起作用,这也是把m标示符放到这里说明的原因。

分组

  上面我们说过,正则表达式是一个字符一个字符的去匹配,所以如果要匹配一个单词如is ,就是必须写/is/, 如果想要匹配is 出现3次,就只能写/isisis/, 我们想使用量词/is{3}/,但这只表示s出现3次,那怎么修改才能表示is 出现三次,把is 用括号括起来,/(is){3}/. 用括号把is括起来,就表示是它是一个整体,一个组,它们要一起出现,才算匹配成功,所以称之为分组。分组有一个重要的概念,就是引用,当正则表达式中有分组时,我们可以获取到分组的内容,怎么获取,就是$n,n表示数字,$1表示第一个分组的内容,$2 表示第二个分组的内容,$3 表示第三个分组的内容,依次类推,其实这里还有一个$0, 它比较特殊,所以单列出来,它表示,整个正则表达式匹配成功的内容。 可能不太好理解,写一个例子

写一个时间字符串 '2017-03-05', 正则表达式 /\d{4}-\d{2}-\d{2}/g 可以匹配它,如下,

let reg = /\d{4}-\d{2}-\d{2}/g;
let string = '2017-03-20'
let replaceString = string.replace(reg,"X");
console.log(replaceString)  //X

  $1, $2$3都是字符串,可以进行任意组合,我们就可以得到想要的结果, '$2/$3/$1', 我们就可以把一种日期格式,转化成另外一种日期格式

let reg = /(\d{4})-(\d{2})-(\d{2})/g;
let string = '2017-03-20'
let replaceString = string.replace(reg,"$2/$3/$1");
console.log(replaceString)  //  03/20/2017

忽略分组:$n获取分组的内容和正则表达式中的分组是一一对应的,正则表达式中有几个分组,它从左向右就会对应几个$n$1 永远获取的是第一个分组内容,$2 永远获取的都是第二个分组的内容,但有时候,我们想跳过某个分组,获取它下一个分组,比如$2 获取第三个分组的内容,这时正则表达式中的第二个分组前面要加 ?:, 表示获取内容的时候可以忽略这个分组

let reg = /(\d{4})-(?:\d{2})-(\d{2})/g;
let string = '2017-03-20'
let replaceString = string.replace(reg,'$2'); // $2
console.log(replaceString)  //20

  在上面的代码中,我们在第二个分组前面加了 ?:进行了忽略了,所以$2 获取的是第三个分组的内容。

  分组还有一个概念,就是重复子项,它用1,2来表示,它们只用在正则表达式中,1 代表的也是第一个分组,2代表的是第二个分组,它们主要的作用是匹配以下这种字符串,

121, 222, 323, 424, 第一个数字和第三个数字相等,但又是不确定的数字, 所以在书写正则表达式时,必须保证第一项和第三项相等,第三项是第一项的复制,1, 就是正则表达式中第一个分组的复制。

let reg = /(\d)2\1/g;
let string = '121 222 323 424'
let replaceString = string.replace(reg,'X');
console.log(replaceString)  // X X X X

  还有一个或的概念,符号表示为|, /ab|ac/, 当它们去匹配字符串时,只要出现其中的一个就算成功

ip 地址变为三位数

var str = "12.34.23.23 4.4.4.4 45.456.456.453" // 假设这是三个ip
str.replace(/(\d+)/g,"00$1").replace(/0*(\d{3})/g,"$1"); // 012.034.023.023 004.004.004.004 045.456.456.453

正则断言

语法如下:

String(Number).replace(/(\d)(?=(\d{3})+$)/g, "$1,");
举例:

String(123456789).replace(/(\d)(?=(\d{3})+$)/g, "$1,");
or

'123456789'.replace(/\B(?=(\d{3})+(?!\d))/g, ',')


//结果是:123,456,789

如果为小数则为:
'1234567890030.7890'.replace(/(?=\B(?:\d{3})+\b)(\d{3}(\.\d+$)?)/g,',$1'); // 整数小数都兼容
方法二:使用toLocaleString()方法
语法如下:

Number.toLocaleString('en-US');
//举例:

(123456789).toLocaleString('en-US');
//结果是:123,456,789

对于中文场景下,toLocaleString('en-US')中的'en-US'理论上是可以缺省的,也就是直接(123456789).toLocaleString()也是可以得到123,456,789。但是如果你的产品可能海外用户使用,则保险起见,还是保留'en-US'

断言,只匹配一个位置
比如,你想匹配一个“人”字,但是你只想匹配中国人的人字,不想匹配法国人的人
就可以用一下表达式
(?<=中国)人
所以,表达式与其他通配符连用才能起到效果。
(?=.*[a-z])\d
这个就表示 匹配以“任意字符连着一个小写字母”开头的数字,只匹配数字。

?!负向预查,非获取匹配

原文链接:

http://caibaojian.com/zhengze-fei.html
正则

非匹配

var reg = ^(?!.*df).*$     df就是你不想匹配的一个字符串了。·



abc@c

abc@d

asdf@aa

asdfsdf@qq·

reg.test('abc@c')

不会匹配到含有 df的内容

?!负向预查,非获取匹配

jsonp转化json实战遇到的问题

qq音乐返回的jsonp数据,但是我们需要json数据,需要正则匹配

jsonp:"MusicJsonCallback({"retcode":0,"code":0,"subcode":0,"lyric":"W3RpOua8lOWRmF0KW2FyO……

我们需要大括号的内容,所以

// 其实我们不需要这个jsonp数据,这里我们做处理

if (typeof ret === 'string') {
  var reg =/^\w+\(({[^()]+})\)$/
  var matches = ret.match(reg)
  if (matches) {
    ret = JSON.parse(matches[1])
  }
}

正则贪婪

  • *? 重复任意次,但尽可能少重复
  • ? 重复1次或更多次,但尽可能少重复
  • ?? 重复0次或1次,但尽可能少重复
  • {n,m}? 重复n到m次,但尽可能少重复
  • {n,}? 重复n次以上,但尽可能少重复

你可能感兴趣的文章

    发表评论

    评论支持markdown,评论内容不能超过500字符
    关于技术问题或者有啥不懂的都可以来 我的视频空间 提问, 推荐作者总结知识点 前端知识体系, 感謝支持!