Преобразуйте параметр в формате Pascal в имя переменной, разделенное подчеркиванием
-
12-09-2019 - |
Вопрос
Это не так просто, как кажется.Большинство из вас, вероятно, думают о регулярном выражении /([A-Z])/_$1/
как я нашел по всему Интернету, но моя конкретная ситуация немного сложнее.Моя исходная строка содержит больше содержимого, которое я не надо хотите, чтобы перед тем, как преобразовать часть, которую я делай.
Рассмотрим обычного сеттера:
public function setUserId()
Конечно, в этом методе отсутствует параметр.Возможно, у меня есть много таких методов.Я бы хотел преобразовать эту строку в
public function setUserId($user_id)
это довольно простая вещь для рассмотрения, но не так просто, как я думаю об этом глубже.Это похоже на то , что Andreas_D в этот поток, но с дополнительной проблемой, связанной с попыткой итеративного изменения имени переменной...
Вероятно, это будет что-то очевидное с использованием регулярных выражений, но я все еще довольно новичок в них.В любом случае, я нигде в своих поисках не могу найти достойного решения этой проблемы.
Редактировать:конечно, я понимаю, что в "общественной функции" нет капиталовложений, которые делали бы ее безопасной.Но этот поиск и подстановка будут выполняться с блоками кода, и я хочу убедиться, что строка, которую я изменяю начинается с "общественной функцией".
Решение
Сначала выполните поиск определений функций, а затем при каждом совпадении вставьте параметр, основанный на имени функции.
/\b(function\s+set([A-Z]\w*))\b\s*\(\)/g
Этот шаблон даст вам совпадения с function
-ключевое слово и имя функции в группе 1, а также часть имени функции в верблюжьем корпусе в группе 2.
/([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))/g
Этот шаблон найдет последнюю букву перед последовательностью прописных и строчных букв, которая составляет camel-case.
Вы не указали, какой язык вы будете использовать, поэтому вот демонстрация с использованием Python:
import re
pattern1 = re.compile(r'\b(function\s+set([A-Z]\w*))\b\s*\(\s*\)')
pattern2 = re.compile(r'([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))')
def fix_setters(code):
def replacer(match):
var_name = pattern2.sub(r'\1_', match.group(2)).lower()
return "%s($%s)" % (match.group(1), var_name)
return pattern1.sub(replacer, code)
Последняя строка ("return pattern1.sub(replacer, code)
"), использует обратный вызов для генерации текста, подлежащего замене.В большинстве языков должна быть аналогичная функциональность.
Python (до версии 3.0) использует оператор modulus ("%
") для форматирования, аналогичного sprintf
например , вязык C.
Пример:
>>> s = """\
... public function setUserName() {
... blaha
... }
... """
>>> print s
public function setUserName() {
blaha
}
>>> print fix_setters(s)
public function setUserName($user_name) {
blaha
}
>>>
Дополнительная информация: .NET - Как вы можете разделить строку с разделителями “caps” на массив?