2016-12-14 79 views
-3

首先,我不是JavaScript專家,實際上我是新手。使用Javascript獲取所有出現在字符串中的正則表達式

我知道PHP,並有函數來獲得所有正則表達式模式的出現preg_match()preg_match_all()

在互聯網上,我發現許多資源顯示如何獲得一個字符串中的所有出現。但是當我做了幾次正則表達式匹配時,它看起來很醜。

這是我在互聯網上找到:

var fileList = [] 
var matches 
while ((matches = /<item id="(.*?)" href="(.*?)" media-type="(?:.*?)"\/>/g.exec(data)) !== null) { 
    fileList.push({id: matches[1], file: matches[2]}) 
} 

fileOrder = [] 
while ((matches = /<itemref idref="(.*?)"\/>/g.exec(data)) !== null) { 
    fileOrder.push({id: matches[1]}) 
} 

難道還有比這個代碼以外的更優雅的方式?

+0

而你的問題是? –

+0

哦。我認爲我做錯了,如果他們需要像這樣的東西,我試圖向像我這樣的新手分享知識。我可以回答我的問題嗎? – Valour

+0

這是一個問答網站,而不是論壇。除非你有關於編程的具體問題,否則你應該刪除它。你甚至可以把這個問題變成一個問題,說「我在這裏使用的方法有什麼問題?」儘管這會比這裏更適合http://codereview.stackexchange.com/。 –

回答

1

在html上使用正則表達式通常被認爲是一個壞主意,因爲正則表達式缺乏足夠的能力來可靠地匹配a^n b^n任意嵌套的事件,例如平衡偏移或HTML/XML打開/關閉標記。它也很容易從JavaScript中獲取數據,而不會像字符串那樣處理它,這就是。例如:

let mapOfIDsToFiles = Array.from(document.querySelectorAll('item')) 
    .reduce((obj, item) => { 
    obj[item.id] = item.href; 
    return obj; 
    }, {}); 

這具有更快額外的優勢,更簡單,更穩健。 DOM訪問速度很慢,但您仍然可以訪問DOM來獲取運行regex的HTML。

修改像String.prototype這樣的內置原型通常被認爲是一個壞主意,因爲它可能會導致與定義相同功能但不同的第三方代碼發生隨機破壞,或者JavaScript標準被更新爲包含該函數但它的工作方式不同。

UPDATE

如果數據已經是一個字符串,你可以很容易地把它變成一個DOM元素不影響頁面:

let elem = document.createElement('div') 
div.innerHTML = data; 
div.querySelectorAll('item'); // gives you all the item elements 

只要你不把它添加到文檔,它只是一個內存中的JavaScript對象。

更新2

是的,這也適用於XML,但其轉換爲DOM是稍微複雜一些:

// define the function differently if IE, both do the same thing 
let parseXML = (typeof window.DOMParser != null && typeof window.XMLDocument != null) ? 
    xml => (new window.DOMParser()).parseFromString(xml, 'text/xml') : 
    xml => { 
    let xmlDoc = new window.ActiveXObject('Microsoft.XMLDOM'); 
    xmlDoc.async = "false"; 
    xmlDoc.loadXML(xml); 
    return xmlDoc; 
    }; 

let xmlDoc = parseXML(data).documentElement; 

let items = Array.from(xmlDoc.querySelectorAll('item')); 

注意,如果解析失敗(即您的文件格式不正確),那麼您將需要檢查錯誤文檔,如下所示:

// check for error document 
(() => { 
    let firstTag = xmlDoc.firstChild.firstChild; 
    if (firstTag && firstTag.tagName === 'parsererror') { 
    let message = firstTag.children[1].textContent; 
    throw new Error(message); 
    } 
})(); 
+0

但是'data'變量沒有加載到DOM。它來自一個文件。如果您知道將字符串轉換爲單獨的DOM而不觸及頁面的實際DOM的方式,那將非常棒。 – Valour

+0

@GokhanOzturk更新了我的答案。 –

+0

如果字符串實際上是一個XML文檔,這也工作嗎? – Valour

0

我想出了在String中創建方法的想法。

我寫了一個String.prototype是simplyfy的事情對我來說:

String.prototype.getMatches = function(regex, callback) { 
    var matches = [] 
    var match 
    while ((match = regex.exec(this)) !== null) { 
    if (callback) 
     matches.push(callback(match)) 
    else 
     matches.push(match) 
    } 

    return matches 
} 

現在我可以得到所有以更優雅的方式匹配。它也類似於PHP的preg_match_all()函數。

var fileList = data.getMatches(/<item id="(.*?)" href="(.*?)" media-type="(?:.*?)"\/>/g, function(matches) { 
    return {id: matches[1], file: matches[2]} 
}) 

var fileOrder = data.getMatches(/<itemref idref="(.*?)"\/>/g, function(matches) { 
    return matches[1] 
}) 

我希望這對你也有幫助。

相關問題