2016-11-27 32 views
2

Here is a Codepen version怪異的行爲與正則表達式匹配

我的目標是遍歷數組的元素,搜索匹配[email protected]的東西@~,刪除標識匹配的那些「書擋」,然後.join()數組。在下面的例子中,結果應該看起來像a/b/c

但是相反,我得到的結果a/[email protected]@~/c。爲了讓事情更加令人困惑,當我顛倒數組元素的順序時,問題結果從[email protected]@~變爲[email protected]@~。最後,把事情非常怪異,這個問題似乎通過把一個簡單test方法,它本身總是返回false值自行解決。查看代碼中的評論。親眼看看。

是什麼原因造成這種奇怪的行爲?迭代這些元素並執行我描述的替換的正確方法是什麼?

function myFunction() { 
 
    var a = ["a", "[email protected]@~", "[email protected]@~"] 
 
    var re = /[email protected](.*?)@~/g; 
 
    var i = a.length; 
 
    // Uncomment below line to see the problem change from [email protected]@~ to [email protected]@~ 
 
    //a.reverse(); 
 
    while (i--) { 
 
    console.log('i', i, 'str', a[i]); 
 
    var match = re.exec(a[i]); 
 
    console.log('match', match); 
 
    // Uncomment the below line to see it work properly. 
 
    //console.log('test', re.test(a[i])); 
 
    if (match && match[0] && match[1]) { 
 
     a[i] = a[i].replace(match[0], match[1]); 
 
     console.log('a[i]', a[i]); 
 
    } 
 
    } 
 
    var res = a.join('/'); 
 
    document.getElementById("demo").innerHTML = res; 
 
}
<p> 
 
    My goal is to print the string: <code>a/b/c</code>. See weird <i>uncomment</i> fix in JS. 
 
    <button onclick="myFunction()">Click Here</button> 
 
</p> 
 
<p id="demo"></p>

+0

是:*串插*。見下面評論接受答案。 – Mowzer

回答

2

的原因的行爲是你的正則表達式具有全局標誌(g),但你只執行一次;這意味着其設置爲lastIndex,並且下次運行它時,它會嘗試從停止的位置開始。

要麼刪除g標誌,或添加

re.lastIndex = -1; 

...作爲while循環的第一行:

function myFunction() { 
 
    var a = ["a", "[email protected]@~", "[email protected]@~"] 
 
    var re = /[email protected](.*?)@~/;    // <=== Note `g` removed 
 
    var i = a.length; 
 
    var t; 
 
    while (i--) { 
 
    var match = re.exec(a[i]); 
 
    if (match && match[0] && match[1]) { 
 
     a[i] = a[i].replace(match[0], match[1]); 
 
    } 
 
    } 
 
    var res = a.join('/'); 
 
    document.getElementById("demo").innerHTML = res; 
 
}
<p> 
 
    My goal is to print the string: <code>a/b/c</code>. See weird <i>uncomment</i> fix in JS. 
 
    <button onclick="myFunction()">Click Here</button> 
 
</p> 
 
<p id="demo"></p>

然而,如果你在正則表達式上留下那個g標誌,你c一個與

a[i] = a[i].replace(re, "$1"); 

function myFunction() { 
 
    var a = ["a", "[email protected]@~", "[email protected]@~"] 
 
    var re = /[email protected](.*?)@~/; 
 
    var i = a.length; 
 
    var t; 
 
    // Uncomment below line to see the problem change from [email protected]@~ to [email protected]@~ 
 
    //a.reverse(); 
 
    while (i--) { 
 
    a[i] = a[i].replace(re, "$1"); 
 
    } 
 
    var res = a.join('/'); 
 
    document.getElementById("demo").innerHTML = res; 
 
}
<p> 
 
    My goal is to print the string: <code>a/b/c</code>. See weird <i>uncomment</i> fix in JS. 
 
    <button onclick="myFunction()">Click Here</button> 
 
</p> 
 
<p id="demo"></p>

...其中也有在形式"[email protected]@[email protected]@~"處理條目(因爲它取代字符串中出現的所有優勢取代while循環的全部內容,不只是第一個)。

+0

+1。但是,假設「$ 1」變量的內容只是一個變量*名稱*,我想用它的值來替換它。 'a [i] = a [i] .replace(re,eval(「$ 1」));'不起作用。有什麼建議麼?如果這會有所幫助,我可以把這個問題放在一個不同的SO問題上? – Mowzer

+1

@Mowzer:在這種情況下,你需要你的循環,沒有'g'標誌或're.lastIndex = -1'。 –