javascript - 正则表达式 - 查找所有以 $_ 开头且位于模板字符串之间任意位置的单词
问题描述
我可以用一个正则表达式解决以下问题吗?我知道它可以用两个单独的正则表达式来完成,但我很好奇它是否可以只用一个来完成?
查找以 $_ 开头的单词(变量)的所有实例,但仅当它们位于模板插值分隔符(<%= 和 %>)之间的任何位置时
因此,使用以下文本:
<div>
<% if ( $_createDiv) { %>
<div>Div created!</div>
<% } %>
<h2>
<span><%= $_var1 %></span>
</h2>
<div><%= markdown.toHTML($_var2 ) %></div>
<div><%= $_var3 +' more text ' + $_var4 %></div>
</div>
预期结果应仅为:$_var1、$_var2、$_var3、$_var4 注意:不应返回 $_createDiv,因为它位于“评估”分隔符中(<% 而不是 <%=)
https://regex101.com/r/dAesYE/1
是否可以使用单个正则表达式来执行此操作,还是需要使用两个?我可以通过运行/(?<=<%=).*(?=%>)/gm
来使用两个来查找分隔符之间的所有文本,然后遍历结果并运行/\B\$_\w+/gm
以获取变量。我只是好奇是否可以使用单个正则表达式。
对于上下文,我试图找到它们,以便我可以运行替换以用函数包围变量名,例如:
myFunc($_var1)
解决方案
假设您可以针对 ECMAScript 2018+ 兼容环境,您可以使用
/(?<=<%=(?:(?!<%=|%>).)*)\B\$_\w+(?=(?:(?!<%=|%>).)*%>)/gs
请参阅正则表达式演示。否则,您应该使用当前的两步方法。
详情:
(?<=<%=(?:(?!<%=|%>).)*)
- 需要其模式立即匹配到当前位置左侧的正向回溯:<%=
- 一个子串(?:(?!<%=|%>).)*
- 任何一个字符,零次或多次出现,尽可能多,不开始一个<%=
或%>
字符序列
\B\$_\w+
- 一个$
char 前面有一个非单词 char_
、 和一个或多个单词字符(?=(?:(?!<%=|%>).)*%>)
- 要求其模式立即匹配到当前位置右侧的正向前瞻:(?:(?!<%=|%>).)*
任何一个字符,零次或多次出现,尽可能多,不开始一个<%=
或%>
字符序列%>
- 一个%>
子串。请参阅 JavaScript 演示:
const regex = /(?<=<%=(?:(?!<%=|%>).)*)\B\$_\w+(?=(?:(?!<%=|%>).)*%>)/gs;
const text = "<div>\r\n <% if ( $_createDiv) { %>\r\n <div>Div created!</div>\r\n <% } %>\r\n <h2>\r\n <span><%= $_var1 %></span>\r\n </h2>\r\n <div><%= markdown.toHTML($_var2 ) %></div>\r\n <div><%= $_var3 +' more text ' + $_var4 %></div>\r\n</div>";
console.log(text.match(regex));
推荐阅读
- node.js - 具有联合类型的 ajv 数组
- node.js - 如何在 React 中有条件地渲染我的组件?根据我的问题,我不知道这是否是一个合适的标题
- r - 将分层json解析为R中的表
- javascript - 两个数组的 Firebase Firestore 查询
- c++ - back_inserter如何判断容器的类型
- cassandra - 连接到 Cassandra 时连接被拒绝
- python - 在哪里可以看到 /usr/lib/python3.x 下的 python 列表代码?
- discord - Discord.js 显示“message.author.tag | message.content”
- java - Concurrent HashMap 不断用 AtomicInteger 给出错误的输出
- vb.net - 在列表框中的各个列下对齐输出数据