使用Javascript获取所有出现在字符串中的正则表达式

问题描述:

首先,我不是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/。 –

在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

我想出了在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] 
}) 

我希望这对你也有帮助。