Регулярное выражение — найти все слова, начинающиеся с $_, которые находятся между строками шаблона.

Могу ли я решить следующее с помощью одного регулярного выражения? Я знаю, что это можно сделать с двумя отдельными регулярными выражениями, но мне любопытно, можно ли это сделать только с одним?

Найти все экземпляры слов (переменных), которые начинаются с $_, но только если они попадают где-то между разделителями интерполирования шаблона (‹%= и %›)

Так со следующим текстом:

<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)

person slopps    schedule 15.02.2021    source источник


Ответы (1)


Предполагая, что вы можете ориентироваться на среды, совместимые с ECMAScript 2018+, вы можете использовать

/(?<=<%=(?:(?!<%=|%>).)*)\B\$_\w+(?=(?:(?!<%=|%>).)*%>)/gs

См. демонстрацию регулярного выражения. В противном случае вам следует использовать текущий двухэтапный подход.

Подробности:

  • (?<=<%=(?:(?!<%=|%>).)*) - a positive lookbehind that requires its pattern to match immediately to the left of the current location:
    • <%= - a substring
    • (?:(?!<%=|%>).)* - любой один символ, ноль или более вхождений, максимальное количество, которое не начинает последовательность символов <%= или %>
  • \B\$_\w+ - символу $, которому предшествует либо символ, не являющийся словом, либо _, либо один или несколько символов слова
  • (?=(?:(?!<%=|%>).)*%>) - a positive lookahead that requires its pattern to match immediately to the right of the current location:
    • (?:(?!<%=|%>).)* any one char, zero or more occurrences, as many as possible, that does not start a <%= or %> char sequence
    • %> - подстрока %>. См. демонстрацию 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));

person Wiktor Stribiżew    schedule 15.02.2021