Регулярные выражения. Получить обработчик события, который передан в метод addEventListener
Необходимо в JS коде найти использование метода addEventListener.
Структура: объект.addEventListener('событие', обработчик, другие_параметры_при_наличии)
В качестве обработчика может быть как ранее объявленная функция (название), так и сама функция с объявлением (function).
Имеется следующее регулярное выражение
import re
from pprint import pprint
REX_ADD_EVENT_LISTENER = re.compile(
r'\s*([A-Za-z0-9_]+).addEventListener\s*\('
r'\s*[\'"`]([a-z]+)[\'"`]\s*,'
r'\s*([A-Za-z0-9_]+|function\s*\(([^)]*)\)\s*{\s*(.+?)})\s*'
r',?\s*(.+)?\);?'
)
js_code = '''\
ctr_switch.addEventListener('mousedown', onMouseDown, false);
ctr_switch.addEventListener('mouseup', onMouseUp, false);
ctr_switch.addEventListener('mouseout', function() {
if (flag) {
setSignal("status", false);
flag = false;
}
}, false);'''
pprint(REX_ADD_EVENT_LISTENER.findall(js_code))
# [('ctr_switch', 'mousedown', 'onMouseDown', '', '', 'false'),
# ('ctr_switch', 'mouseup', 'onMouseUp', '', '', 'false'),
# ('ctr_switch', 'mouseout', 'function', '', '', '(')]
Если обработчиком является название функции, все работает нормально (хотя есть лишние пустые строки в результате), но вот вытащить функцию, которая определена с помощью function, не получается (нужно и тело этой функции).
Подскажите, пожалуйста, как доработать регулярное выражение.
Стрелочные функции искать не нужно.
Простую функцию получаю с помощью следующего регулярного выражения:
import re
from pprint import pprint
REX_FUNCTION = re.compile(
r'(?ms)function\s+([A-Za-z0-9_]+)\s*\([^)]*\)\s*{\s(.+?)^}')
js_code = '''\
function onMouseDown() {
setSignal("status", true);
flag = true;
}
ctr_switch.addEventListener('mousedown', onMouseDown, false);'''
pprint(REX_FUNCTION.findall(js_code))
# название функции тело
# [('onMouseDown', ' setSignal("status", true);\n flag = true;\n')]
Возможно получить примерно такой же результат для функции из addEventListener (без названия, конечно).
Ответы (1 шт):
Вот так вот (основная проблема была в том, что . не находит переводы строк в теле функции (заменить на [\s\S] или добавить s флаг), но ещё упростил по мелочи):
\s*(\w+)\.addEventListener\s*\(\s*['\"`]([a-z]+)['\"`]\s*,\s*(function\s*\(([^)]*)\)\s*{\s*[\s\S]*}|\w+)\s*,?\s*(.+)?\);?
Тест https://regex101.com/r/vwlt8s/3
Сгенерированный код:
# coding=utf8
# the above tag defines encoding for this document and is for Python 2.x compatibility
import re
regex = r"\s*(\w+)\.addEventListener\s*\(\s*['\"`]([a-z]+)['\"`]\s*,\s*(function\s*\(([^)]*)\)\s*{\s*[\s\S]*}|\w+)\s*,?\s*(.+)?\);?"
test_str = ("ctr_switch.addEventListener('mousedown', onMouseDown, false);\n"
"ctr_switch.addEventListener('mouseup', onMouseUp, false);\n"
"ctr_switch.addEventListener('mouseout', function() {\n"
" if (flag) {\n"
" setSignal(\"status\", false);\n"
" flag = false;\n"
" }\n"
"}, false);")
matches = re.finditer(regex, test_str, re.MULTILINE)
for matchNum, match in enumerate(matches, start=1):
print ("Match {matchNum} was found at {start}-{end}: {match}".format(matchNum = matchNum, start = match.start(), end = match.end(), match = match.group()))
for groupNum in range(0, len(match.groups())):
groupNum = groupNum + 1
print ("Group {groupNum} found at {start}-{end}: {group}".format(groupNum = groupNum, start = match.start(groupNum), end = match.end(groupNum), group = match.group(groupNum)))
# Note: for Python 2.7 compatibility, use ur"" to prefix the regex and u"" to prefix the test string and substitution.
А "пустые строки" в результате потому, что у функции в примере нет параметров, поэтому группа 4 пустая.