Преобразуйте параметр в формате Pascal в имя переменной, разделенное подчеркиванием

StackOverflow https://stackoverflow.com/questions/1119141

Вопрос

Это не так просто, как кажется.Большинство из вас, вероятно, думают о регулярном выражении /([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” на массив?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top