Excel Power Query使用Web.Page运行正则返回匹配项及子匹配失败求助
Power Query 正则匹配问题修正方案
现有代码核心问题
- 变量引用错误:代码中
m1 = m1[Data]{0}[Children]存在自引用逻辑错误,应改为引用上一步输出的m0变量 - JS特性不兼容:Power Query的
Web.Page接口依赖旧版IE内核渲染,不支持ES2022新增的match.indices属性,调用该属性会直接抛出异常导致匹配逻辑中断,同时d正则标志也不被旧内核支持 - 逻辑冗余错误:循环写入列表项时重复将全部匹配结果序列化后写入每个列表项,而非单个匹配值
修正后兼容Excel的完整代码
let input = "a1b2c3", regexPattern = "\d+", // 注意不要加d标志,旧IE内核不支持 regexFlags = "gm", Match = (input as text, pattern as text, optional flags as text) as list => let // 转义输入文本避免JS语法错误 escapeJS = (str as text) as text => Text.Replace(Text.Replace(str, "'", "\'"), "\", "\\"), html = Text.FromBinary(Text.ToBinary(" <html> <body> <ul id='Matches'></ul> <script> var input = '" & escapeJS(input) & "'; var pattern = '" & escapeJS(pattern) & "'; var flags = '" & (if flags = null then "g" else escapeJS(flags)) & "'; var re = new RegExp(pattern, flags); try { var m = getMatches(input, re); var list = document.getElementById('Matches'); for (var i = 0; i < m.length; i++){ var li = document.createElement('li'); li.textContent = m[i]; list.appendChild(li); } } catch (e) { var li = document.createElement('li'); li.textContent = 'ERROR:' + e.message; list.appendChild(li); } function getMatches(str, re) { var matches = []; var match; while ((match = re.exec(str)) !== null) { // 遍历所有捕获组,包含完整匹配项 for (var i = 0; i < match.length; i++) { if (match[i] != null) { matches.push(match[i]); } } // 防止零宽匹配导致死循环 if (re.lastIndex === match.index) { re.lastIndex++; } } return matches; } </script> </body> </html> ")), page = Web.Page(html), // 提取匹配结果列表 result = try page{0}[Data]{0}[Children]{0}[Children]{1}[Children] otherwise error "匹配失败", // 提取文本内容 output = List.Transform(result, each _[Text]) in output, // 调用函数直接得到匹配结果列表 匹配结果 = Match(input, regexPattern, regexFlags) in 匹配结果
使用说明
- 上述代码直接在Excel Power Query的高级编辑器中粘贴即可运行,示例输入的返回结果为
{"1","2","3"} - 支持带捕获组的正则模式,会按匹配顺序返回所有捕获组的非空值
- 完全兼容Excel 2016及以上所有版本,无需额外配置或插件
内容的提问来源于stack exchange,提问作者PJE
相关产品推荐
相关产品推荐

