[记录] JavaScript 中的正则表达式(案例分析)

正则可视化工具: Regexper

案例分析:

匹配16进制颜色值

要求匹配:
#ffbacd、#FC01ad、#FFF、#ffE

分析:

// 16进制字符, 可以用字符组 [0-9a-fA-F]
// 字符可以出现3 或 6次, 需要用到量词和分支结构
// 使用分支时,需要注意顺序

var reg = /#([0-9a-fA-f]{6}|[0-9a-fA-f]{3})/g;

"#ffbacd;#FC01ad;212#FFF;#ffE1".match(reg);
// ["#ffbacd", "#FC01ad", "#FFF", "#ffE"]

 

匹配24小时制的时间

匹配要求:
08:59、23:59、3:7
分析:
时间划分 - 小时:
上午 00点到09点(0可选); 白天10点到19点;晚上20点到23点;
方法一: 第一位是[01],则第二位是[0-9], 如果第一位是2,则第二位[0-3]
[01]?[0-9]|2[0-3]

方法二: 分为[0-3]和[4-9]

[012]?[0-3]|[01]?[4-9]

分钟: 00分钟到59分钟; 第一个数范围在0-5之间, 第二个数在0-9之间;
[0-5][0-9]

最终结果:
用于复杂的字符串搜索替换时, 如: "跑步用时19:50", 表示的是19分50秒;
由于是在整个字符串中查找,用到了\b单词的开始和结束

/\b(?:[01]?[0-9]|2[0-3]):[0-5][0-9]\b/
// 或者
/\b(?:[012]?[0-3]|[01]?[4-9]):[0-5][0-9]\b/

var reg = /\b(?:[01]?[0-9]|2[0-3]):[0-5][0-9]\b/g;
"18:30开始跑步,18:52结束,用时22:30".match(reg);
// ["18:30", "18:52", "22:30"]


用于数据验证, 如表单中的字符串必须是24小时制的时间 08:59

/^(?:[01]?[0-9]|2[0-3]):[0-5][0-9]$/
// 或者
/^(?:[012]?[0-3]|[01]?[4-9]):[0-5][0-9]$/

var reg = /^(?:[012]?[0-3]|[01]?[4-9]):[0-5][0-9]$/;
reg.test("08:59");
// true

 

数字的千分位分隔表示法

// 示例 (数字, 从右往左, 每隔3个用逗号分隔)
// 把 "12345678", 变成 "12,345,678"

// 因为逗号出现的位置, 要求3个数字一组, 至少出现一次
// /(\d{3})+/
// 从右往左 用先行正向断言 
var reg = /(?=(\d{3})+$)/g;
"12345678".replace(reg, ",");
// "12,345,678"

// 正则表示, 从结尾向前数,是3的倍数,就把其前面的位置替换成逗号。
"123456789".replace(reg, ",");
// ",123,456,789" 

// 解决方案:
// 要求匹配到的这个位置不能是开头
// (?!^) 先行逆向断言, 非开头
var reg = /(?!^)(?=(\d{3})+$)/g;
"123456789".replace(reg, ",");
// "123,456,789"

// 把"12345678 123456789", 替换成"12,345,678 123,456,789"
// 此时需要把正则里的开头^和结尾$,替换成\b
var reg = /(?!\b)(?=(\d{3})+\b)/g;
"12345678 123456789".replace(reg, ",");
// "12,345,678 123,456,789"

// 其中的(?!\b) 表示的是非单词边界, 等价于 \B
// /\B(?=(\d{3})+\b)/g;

 

去掉字符串首尾空白符

匹配到开头和结尾的空白符,然后替换成空字符串.

var reg = /^\s+|\s+$/g;
" Miss You!   ".replace(reg, "");
// "Miss You!"


匹配整个字符串, 用引用来提取相应的数据

// 这里使用*?惰性匹配,不然也会匹配对一个空格之前的所有空格
var reg = /^\s*(.*?)\s*$/g;
" Miss You!   ".replace(reg, "$1");
// "Miss You!"

 

将每个单词的首字母转为大写

// 思路: 找到每个单词的首字母, 开头是字母或\s空格后是字母的
function firstLetterToUpperCase(str){
    var reg = /(?:^|\s)\w/g;
    return str.toLowerCase().replace(reg, function(c){
        return c.toUpperCase();
    });    
}
console.log( firstLetterToUpperCase("my    name is epeli!") );
// "My    Name Is Epeli!"

 

驼峰化

function camelize(str){
    var reg = /[-_\s]+(.)?/g;
    return str.replace(reg, function(match, c){
        return c ? c.toUpperCase() : "";
    });
}
console.log(camelize('--moz-transform _class-name'));
// "MozTransformClassName"

 

逆转驼峰化

function dasherize(str){
    var reg = /([A-Z])/g;
    str = str.replace(reg, "-$1");
    var reg = /[-_\s]+/g;
    str = str.replace(reg, "-");
    return str.toLowerCase()
}
console.log( dasherize("MozTransform") );
// "-moz-transform"

 

匹配HTML成对标签

// 匹配要求:
<title>标题</title>
<p>段落</p>

// 不匹配: 
<title>不成对<p>

// 匹配一个开始标签, <[^>]+>
// 匹配一个结束标签, <\/[^>]+>
// 为了匹配成对的标签, 需要使用反向引用
// <([^>]+)> 结束标签反向引用前面的分组 <\/\1>
// [\d\D] 表示的是数字或者不是数字。也就是匹配任意字符
// [^>] 表示匹配除>以为的任意字符

var reg = /<([^>]+)>[\d\D]*<\/\1>/g;
reg.test("标题"); // true
reg.test("

段落

"); // true
reg.test("<p>error</title>"); // false

 

匹配身份证号

/^(\d{15}|\d{7}[\dxX])$/

// 正则分成两部分
// \d{15} 表示15位连续数字
// \d{17}[\dxX] 表示17位连续数字,最后可以是数字或大小写"x"

 

使用构造函数生成正则表达式

// getElementsByClassName 函数的实现思路:
// A. 比如要获取className为 "item" 的dom元素
// B. 首先生成一个正则 /(^|\s)item(\s|$)/;
// C. 然后再逐一验证页面上的所有dom元素的类名,取满足匹配的元素

function getElementsByClassName(className){
    // 获取页面中所有的标签元素
    var elements = document.getElementsByTagName('*');
    var reg = new RegExp("(^|\\s)" + className + "(\\s|$)");
    var result = [];
    for (var i = 0; i < elements.length; i++){
        var element = elements[i];
        if( reg.test(element.className)){
            result.push(element);
        }
    }
    return result;
}
console.log( getElementsByClassName('item') );
// [a.item, div.item, p.item, ...]


posted @ 2018-09-08 11:49  yuxi2018  阅读(290)  评论(0编辑  收藏  举报