正则表达式

闲着无聊,系统的研究一下正则表达式

正则历史的讲解就算了,没有那么博学,直接上基础知识点吧.

正则表达式的文字模板是有很多不同类型的字符组成的,包括:元字符,转义字符,限定符,字符组,或结构,括号分组

1.元字符

字符 含义
. 匹配除了换行符(n)以外的所有字符
w 匹配字母,数字,或则汉字
W 匹配除了字母,数字,汉字以外的其他字符
d 匹配数字
D 匹配除了数字以外的其他字符
s 匹配任意的空白符(f,n,r,t,v)
S 匹配空白符以外的任意字符
b 匹配单词的开始或则结束
B 匹配单词的非开始或则结束
^ 匹配行首
$ 匹配行尾

 

 

 

 

 

 

 

 

 

 

 

 

2.转义字符

*+?|{[()]}^$.#和空白 这些字符都是需要转义的,如果我们要匹配{,就要使用\{

3.限定符

字符 含义
* 匹配零次至多次
+ 匹配一次至多次
? 匹配零次或一次
{2,} 至少匹配两次
{10} 匹配10次
{2,8} 至少匹配两次,至多匹配八次

 

 

 

 

 

 


4.字符组

中括号字符组用来匹配括号内的字符之一.  例

'fasfagxfasdfyfasfz'.split(/[xyz]/) //["fasfag", "fasdf", "fasf", ""]

还有一种排除性字符组

'xaxbycz'.split(/[^xyz]/) //["x", "x", "y", "z"]

或结构|

例如c|d匹配c或则d

/c|d/.test('af') // false
/c|d/.test('ad') // true

括号分组

(cd){1,} 可以匹配cdcd..等, 其中cd便是一个分组

/(cd){1,}$/.test('cdcd') //true

5.贪婪模式和非贪婪模式

默认情况下,所有的限定词都是贪婪模式,表示尽可能多的去捕获字符.而在限定词后增加'?',则是非贪婪模式,表示尽可能少的去捕获字符

'ccccccd'.match(/c+/) //["ccccc"], 贪婪模式, 捕获所有
'ccccccd'.match(/c+?/) //["c"], 非贪婪模式, 只捕获到第一个

6.捕获分组

在实际应用中我们很有可能需要获取到匹配的字符串,例如我们要将字符串"万里碧空飘着朵朵白云"替换成"万里碧空没有一朵白云"

"万里碧空飘着朵朵白云".replace(/(万里碧空)飘着朵朵白云/, '$1没有一朵白云')

注:

反斜杠+number这种引用可以在正则表达式中使用,可用于匹配不同位置的相同子串,例如:

'www.bai.bai.com'.replace(/([a-z]+)\.\1/, '$1') // www.bai.com

非捕获性分组

非捕获性分组,通常由一对括号加上”?:”加上子表达式组成,非捕获性分组不会创建反向引用,就好像没有括号一样。捕获性分组和无捕获性分组在搜索效率方面也没什么不同,没有哪一个比另一个更快。

/^(?:\d+)/

 

一、正则表达式的方法

1.test

检索字符串中的指定子串,返回布尔值

/^\d[a-zA-Z]{3}$/.test('1aac') // true

2.exec

返回一个数组,数组中的第一个条目是第一个匹配

/^\d[a-zA-Z]{3}$/.exec('1aac') // ["1aac"]

二、String可以使用正则表达式的方法

1.search

返回子串的开始位置,

'a12b2334c34'.search(/\d{4}/) // 4

2.match

返回匹配到的子串,返回出来的是数组

'a12b2334c34'.match(/\d{4}/) // ["2334"]
'sld12345s1515f'.match(/\d{4}/g)  //["1234", "1515"]

3.replace

替换匹配到的子串,返回值为替换过的子串

'a12b2334c34'.replace(/\d{4}/, 'cccc') // "a12bccccc34"

4.split

将字符串分割成数组,返回值为分割成的数组

'a12b2334c34'.split(/\d{4}/) // ["a12b", "c34"]

三、断言

1.正向先行断言 (?=exp)

代表字符串中的一个位置,紧接该位置之后的字符序列能够匹配 exp

/f(?=234)/.test('123abcf234acd') //true

2.负向先行断言(?!exp)

代表字符串中的一个位置,紧接该位置之后的字符序列不能匹配 exp

/f(?!234)/.test('123abcf234acd') //false

四、常用的正则表达式

1.Email地址:

^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$

2.URL验证

[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$

3.手机号码验证

/^((1[3-8][0-9])+\d{8})$/

4.汉字验证

^[\u4e00-\u9fa5]{0,}$

5.手机号码中间四位替换****

var str = '15500000000';
var str0 = str.replace(/^(\d{3})\d{4}(\d{4})/g,'$1****$2');
console.log(str,str0);  //15500000000  155****0000

6.校验身份证号码

15位:

^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$

18位:

^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9]|X)$

7.校验日期

“yyyy-mm-dd“ 格式的日期校验,已考虑平闰年。

^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$

8.校验金额

金额校验,精确到2位小数。

^[0-9]+(.[0-9]{2})?$

9.一些填写卡号效果

<input type="text" name="code" id="code" />
$('#code').bind('input propertychange', function() {  //绑定的方法
    var val = $(this).val(),
        val = val.replace(/-/g, ''),  //如果用户输入-,则替换为空
        valArr = val.split(''),
        newVal = '';

    for(var i = 0, len = valArr.length - 1; i <= len; i++) {
        newVal += valArr[i] + ((i && (i % 4 == 3) && i != len) ? '-' : '');
    }  //处理

    $(this).val(newVal.toUpperCase());  //将小写转换成大写
    set_text_value_position('code', -1);  //强制光标在最后面的函数
});
//封装的强制光标在最后面的函数
function set_text_value_position(obj, spos) {
    var tobj = document.getElementById(obj);
    if(spos < 0)
        spos = tobj.value.length;
    if(tobj.setSelectionRange) { //兼容火狐,谷歌
        setTimeout(function() {
            tobj.setSelectionRange(spos, spos);
            tobj.focus();
        }, 0);
    } else if(tobj.createTextRange) { //兼容IE
        var rng = tobj.createTextRange();
        rng.move('character', spos);
        rng.select();
    }
}

10.数字格式化:  1234567890 --> 1,234,567,890

非正则的实现:

let test = '1234567890'

function formatCash(str) {
  let arr = []

  for (let i = 1; i < str.length; i++) {
    if (str.length % 3 && i == 1)
      arr.push(str.substr(0, str.length % 3))

    if (i % 3 === 0)
      arr.push(str.substr(i - 2, 3))

  }

  return arr.join(',')
}

console.log(formatCash(test)) // 1,234,567,890

用正则实现:

let test1 = '1234567890'
let format = test1.replace(/\B(?=(\d{3})+(?!\d))/g, ',')

console.log(format) // 1,234,567,890

下面简单分析下正则/\B(?=(\d{3})+(?!\d))/g

  1. /\B(?=(\d{3})+(?!\d))/g:正则匹配边界\B,边界后面必须跟着(\d{3})+(?!\d);
  2. (\d{3})+:必须是1个或多个的3个连续数字;
  3. (?!\d):第2步中的3个数字不允许后面跟着数字;
  4. (\d{3})+(?!\d):所以匹配的边界后面必须跟着3*n(n>=1)的数字。

11.去掉字符串左右两边的空格

非正则实现:

function trim(str) {
    let start, end
    for (let i = 0; i < str.length; i++) {
        if (str[i] !== ' ') {
            start = i
            break
        }
    }
    for (let i = str.length - 1; i > 0; i--) {
        if (str[i] !== ' ') {
            end = i
            break
        }
    }

    return str.substring(start, end - 1)
}


let str = "  jaw il "
console.log(trim(str)) // "jaw il"

正则实现:

function trim(str) {
    return str.replace(/(^\s*)|(\s*$)/g, "")
}

let str = "  jaw il "
console.log(trim(str)) // "jaw il"

12.字符串数组去重   ['a','b','c','a','b','c'] --> ['a','b','c']

这里只考虑最简单字符串的数组去重,暂不考虑,对象,函数,NaN等情况,这种用正则实现起来就吃力不讨好了。

非正则实现:

//es6实现
let str_arr=["a","b","c","a","b","c"]

function unique(arr){
  return [...new Set(arr)]
}

console.log(unique(str_arr)) // ["a","b","c"]
//es5实现
var str_arr = ["a", "b", "c", "a", "b", "c"]

function unique(arr) {
    return arr.filter(function(ele, index, array) {
        return array.indexOf(ele) === index
    })
}

console.log(unique(str_arr)) // ["a","b","c"]
//es3实现
var str_arr = ["a", "b", "c", "a", "b", "c"]

function unique(arr) {
    var obj = {},
        array = []

    for (var i = 0, len = arr.length; i < len; i++) {
        var key = arr[i] + typeof arr[i]
        if (!obj[key]) {
            obj[key] = true
            array.push(arr[i])
        }
    }
    return array
}

console.log(unique(str_arr)) // ["a","b","c"]

正则实现:

var str_arr = ["a", "b", "c", "a", "b", "c"]

function unique(arr) {
    return arr.sort().join(",,").
    replace(/(,|^)([^,]+)(,,\2)+(,|$)/g, "$1$2$4").
    replace(/,,+/g, ",").
    replace(/,$/, "").
    split(",")
}

console.log(unique(str_arr)) // ["a","b","c"]

13.手机号强制输入数字,且不能超过11位

$('#tel').on('input prototychange',function () {
    $(this).val($(this).val().replace(/\D/g,''));    //将所输入的非数字字符替换为空字符
    if ($(this).val() >= 12) {
        $(this).val($(this).val().slice(0,11));      //如果输入字符大于等于12位,则只取其前11位为其值
    }
});    //引入jq所写

 

 

 

以后,再补充...

 

posted @ 2017-03-29 17:43  上山打松鼠  阅读(330)  评论(0编辑  收藏  举报