Javascript正則表達式難點、重點

重複的貪婪性

{n,m}   {n,}   {n}   ?   +   *
  • ?表示匹配0次或1次,(最多匹配1次);javascript

  • +表示匹配1次或屢次,(最少匹配1次);java

  • *表示匹配0次或屢次,(匹配任意次);正則表達式

  • {m,n}表示匹配m到n次,(最少m次,最多n次);bash

舉例:dom

console.log("@123@456@789".match(/\d{1,2}/g))
// ==> ["12", "3", "45", "6", "78", "9"]

{1,2}優先匹配2次(貪婪),還能夠匹配1次,能夠看到上面的結果爲["12", "3", "45", "6", "78", "9"];
非貪婪,在量詞後面加一個?便可;3d

console.log("@123@456@789".match(/\d{1,2}?/g))
// ==> ["1", "2", "3", "4", "5", "6", "7", "8", "9"]

表示匹配到1次了就再也不匹配了(非貪婪)。code

分組

假設有這樣不一樣格式的日期(2016-10-1五、2016/10/1五、2016.10.15),若是想要提取具體的年月日,能夠這麼寫:ip

console.log("2016-10-15".match(/\d{4}[\/\-\.]\d{2}[\/\-\.]\d{2}/))
// ==> ["2016-10-15"]

上面是沒有添加分組時候的,此時,能夠給它添加分組:字符串

console.log("2015-10-15".match(/(\d{4})[\/\-\.](\d{2})[\/\-\.](\d{2})/))
// ==> ["2016-10-15", "2016", "10", "15"]

能夠看到輸出的結果是一個array,裏面的年月日就已經被提取出來了。接下來再看:get

console.log("2015-10-15".replace(/(\d{4})[\/\-\.](\d{2})[\/\-\.](\d{2})/g,"$3-$2-$1"))
// ==> "15-10-2016"

能夠看到結果變成了:15-10-2016,這是由於表達式匹配的內容能夠用$1,$2,...來表示
忽略分組(非捕獲分組)

var reg = /(?:\d{4})(\-|\.|\/)\d{2}\1\d{2}/;
console.log(reg.test('2016-10-15'));    // ==>true
console.log(reg.test('2016.10.15'));    // ==>true
console.log(reg.test('2016/10/15'));    // ==>true
console.log(reg.test('2016-10/15'));    // ==>false

再來一個例子:

console.log("1-2-3-4".replace(/(\d)/g,"x"));
// ==> x-x-x-x
console.log("1-2-3-4".replace(/(-\d)/g,"x"));
// ==> 1xxx
console.log("1-2-3-4".replace(/-(\d)/g,"x"));
// ==> 1xxx
console.log("1-2-3-4".replace(/(-\d)/g,"0$1"));
// ==> 10-20-30-4
console.log("1-2-3-4".replace(/-(\d)/g,"0$1"));
// ==> 1020304
console.log("1-2-3-4".match(/(-\d)/g));
// ==> ["-2", "-3", "-4"]
console.log("1-2-3-4".match(/-(\d)/g));
// ==> ["-2", "-3", "-4"]
console.log(RegExp.$1);
// ==> 4

再來個時間轉化的例子:

var date="2014-12-30 12:30:20";
console.log(date.replace(/(\d{4})-(\d{2})-(\d{2})/g,"$2-$3-$1"));
// ==> "12-30-2014 12:30:20"
console.log(date.replace(/(\d{4})-(\d{2})-(\d{2})\s[\w+\:]{8}/g,"$2-$3-$1"))
// ==> "12-30-2014"

向前查找 (此東西是個位置!)

即(?=p)和(?!p)。其中p是一個子正則表達式。關於錨字符匹配的問題,在ES5中總共有6個。

^ $ \b \B (?=p) (?!p)

(?=3)表示啥意思呢?表示3前面的位置,見例子:

console.log("a1b2c3d4".replace(/(?=3)/g,"x"));
// ==> a1b2cx3d4
console.log("a1b2c3d4".replace(/(?=\d)/g,"x"));
// ==> ax1bx2cx3dx4

那麼(?!...)的概念也好理解了,表示取非的,見例子:

console.log("a1b2c3d4".replace(/(?!3)/g,"x"));
// ==> xax1xbx2xc3xdx4x
console.log("a1b2c3d4".replace(/(?!\d)/g,"x"));
// ==> xa1xb2xc3xd4x

注意(?!d)表示的意思不是「非數字前面的位置」,而是全部位置中扣掉數字前面位置。
再來看一個例子:
假如」a1b2c3d4「這個字符串,我要匹配b或c前面的數字,怎麼作呢?

console.log("a1b2c3d4".replace(/\d(?=[bc])/g,"x"));
// ==> axbxc3d4
console.log("a1b2c3d4".match(/\d(?=[bc])/g));
// ==> ["1", "2"]

再來看一個:假若有這樣一個字符串"a1a2a3a4a5",我要匹配全部的a但不包括3前面的a,怎麼作呢?見下面:

console.log("a1a2a3a4a5".replace(/a(?!3)/g,"x"));
// ==> x1x2a3x4x5

最後:來個小例子結束本篇文章:(利用正則來獲取dom的class)

<div class="box"></div>
<script>
    function getByClass(oParent, sClass) {
        var tag = oParent.getElementsByTagName('*');
        var arr = [];
        var reg = new RegExp('\\b' + sClass + '\\b', "i");
        for (var i = 0; i < tag.length; i++) {
            if (reg.test(tag[i].className)) {
                arr.push(tag[i])
            }
        }
        return arr;
    }
    function findClassInElements(className, type) {
        var ele = document.getElementsByTagName(type || '*');
        var result = [];
        var reg = new RegExp('(^|\\s)' + className + '(\\s|$)');
        for (var i = 0; i < ele.length; i++) {
            if (reg.test(ele[i].className)) {
                result.push(ele[i])
            }
        }
        return result
    }
    console.log(getByClass(document.body, "box"));
    console.log(findClassInElements('box'));
    var box = findClassInElements('box')

    box.forEach(function(value,index){
        console.log(value);
    })
</script>
相關文章
相關標籤/搜索