首页 > 解决方案 > 使用正则表达式从 XML 字符串中提取 URL 和 CDATA

问题描述

描述

我正在尝试从 XML 中提取 URLS 和/或 CDATA。我目前的解决方案效果很好,但只返回第一个元素。如何使用这个特定的正则表达式返回多个元素?

XML 的格式为:

<MediaFile>
https://some_url.com/file.mp4
</MediaFile>
<MediaFile>
https://some_url2.com/file.mp4
</MediaFile>

<MediaFile>
<!CDATA some data here with spaces sometimes>
</MediaFile>
...etc

我想要达到的目标

在我的示例中,有 3 个媒体文件标签,我正在尝试提取 3 个不同的 URL 和 CDATA。最终的解决方案应该类似于

1st url https://example1.com/file.mp4
2nd url https://example2.com/file.mp4
3rd url <!CDATA some data example>

我试过的:

链接到正则表达式101

const data = `<MediaFile delivery="progressive" width="640" height="360" type="video/mp4" bitrate="397" scalable="false" maintainAspectRatio="false">https://example1.com/file.mp4</MediaFile><MediaFile delivery="progressive" width="1024" height="576" type="video/mp4" bitrate="1280" scalable="false" maintainAspectRatio="false">https://example2.com/file.mp4</MediaFile><MediaFile delivery="progressive" width="1024" height="576" type="video/mp4" bitrate="1280" scalable="false" maintainAspectRatio="false"><!CDATA some data example></MediaFile>`;

const regex = /<MediaFile[^>]*type="video\/mp4"[^>]*>([\s\S]*?)<\/MediaFile>/gm;

const res = regex.exec(data);

console.log('1st url', res[1]);
console.log('2nd url', res[2]);
console.log('3rd url', res[3]);

标签: javascriptregex

解决方案


最好不要使用正则表达式,而是使用document.querySelectorAll()解析它的方法:

const data = `<MediaFile delivery="progressive" width="640" height="360" type="video/mp4" bitrate="397" scalable="false" maintainAspectRatio="false">https://example1.com/file.mp4</MediaFile><MediaFile delivery="progressive" width="1024" height="576" type="video/mp4" bitrate="1280" scalable="false" maintainAspectRatio="false">https://example2.com/file.mp4</MediaFile><MediaFile delivery="progressive" width="1024" height="576" type="video/mp4" bitrate="1280" scalable="false" maintainAspectRatio="false"><!CDATA some data example></MediaFile>`;

var o=document.createElement('div');o.innerHTML=data.replace(/<!CDATA/g,'!CDATA');
var arr=Array.from(o.querySelectorAll('MediaFile'))
             .map(el=>el.innerHTML.replace('!CDATA','<!CDATA')
                                  .replace('&gt;','>'))

console.log(arr.join('\n'));

通过一点“额外的努力”,您可以在创建 DOM 元素之前<!CDATA ... >用 a 屏蔽这些部分,然后通过应用MediaFile 元素的-strings其“恢复”为预期的形式。replace().replace('!CDATA','<!CDATA').replace('&gt;','>'.innerHTML


推荐阅读