Как я могу использовать регулярные выражения для анализа js имен классов вместе с кодом, заключенным в него? - PullRequest
0 голосов
/ 22 февраля 2020

Я пытаюсь проанализировать имя класса и содержимое, заключенное в класс js, с помощью регулярных выражений. Я использую python для анализа. Вот пример кода, который я пытаюсь разобрать. То, что я ожидаю получить путем сопоставления с регулярным выражением, это список имен классов и всего содержимого внутри класса (все методы, переменные)

class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}

class Square {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}

Я написал этот шаблон, чтобы соответствовать приведенному выше коду

class\s(.*)\{(.*)\}

Но это совпадает по-разному, как показано на рисунке

enter image description here

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

Ответы [ 2 ]

2 голосов
/ 22 февраля 2020

Используйте библиотеку Pypi regex , которая поддерживает рекурсивное регулярное выражение, это будет работать для любого количества подблоков:

import regex

strin = '''
class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}

class Square {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}
'''
res = regex.findall(r'(class\s+\w+\s+({(?:[^{}]+|(?2))*}))', strin)
print res[0][0]
print '----------------------------------------'
print res[1][0]

Вывод:

class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}
----------------------------------------
class Square {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}

Демонстрация и объяснение (с использованием PCRE, поскольку regex101 не использует модуль regex)

2 голосов
/ 22 февраля 2020

TL; DR: class\s+(.+?)\{(.+?)\n\} должно сработать

Есть две проблемы с вашим попытанным решением

  1. Вы используете жадный квантификатор ((.*)\{) для группа имени класса, где требуется ленивый квантификатор ((.+?)\{). Это вызывает переполнение группы захвата до тех пор, пока не произойдет окончательное вхождение \{.
  2. . Вам также понадобится ленивый квантификатор ((.+?)\n\}), чтобы определять, когда группа захвата для тела класса заканчивается. Это будет работать только для отформатированного кода, где класс явно заканчивается на \n, поскольку всем остальным экземплярам } будет предшествовать отступ. Я не верю, что возможно создать регулярное выражение, которое может отделить тело класса в общем случае, к сожалению.

Редактировать: я также заменил ваши * с + ses, где я думаю, что это уместно, чтобы утверждать, что какой-то символ должен появиться в имени класса и в теле класса

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...