CamelCase2snake_case ()

13

Напишите функцию для преобразования текста CamelCased в snake_case: FunctionForHTMLManipulationстановитсяfunction_for_html_manipulation

Входной текст будет одним подходящим идентификатором на многих языках. Он должен начинаться с английской буквы, а затем следовать за любым количеством английских букв или цифр. Другие символы (пробелы, символы и т. Д.) Не допускаются.

Каждое «слово» в тексте в формате CamelCase будет начинаться с заглавной буквы, кроме как в начале текста или сразу после цифры, и после него будет следовать ноль или более букв, все в одном и том же регистре. Группы цифр будут рассматриваться как отдельные слова, но проходить без изменений.

Другими словами, строчная буква, за которой следует заглавная буква, обозначает разрыв слова. Любая буква и цифра рядом друг с другом указывают на разрыв слова. Заглавная буква, за которой следуют еще одна заглавная буква и строчная буква, обозначает разрыв слова.

...lU...=> ...l_u...
...l9...=> ...l_9...
...U9...=> ...u_9...
...9l...=> ...9_l...
...9U...=> ...9_u...
...UUl...=>...u_ul...

Оба так Buy24Beersи buy24beersстановятся buy_24_beers.
MacDonaldAndObrianстановится mac_donald_and_obrian.
MACDonaldAndOBrianстановится mac_donald_and_o_brian.

CJ Деннис
источник
6
« MACDonaldAndOBrianстановится mac_donald_and_o_brian» - почему?
Qwertiy
2
@Qwertiy Потому что я думал, что эти имена будут веселыми. Если вы не спрашиваете о правиле, которое покрыто ...UUl...=> ...u_ul....
CJ Деннис
Очень тесно связаны
цифровая травма
@DigitalTrauma Удивительно близко к моему первоначальному вопросу, но без претензий на то, что это два вопроса в одном и никаких отрицательных голосов! Самая большая разница в обработке строк ALLCAPS. Я искал, чтобы узнать, задавался ли вопрос раньше, но я не нашел его.
CJ Деннис
1
@ggorlen ...указывает, что это в середине строки.
CJ Деннис

Ответы:

7

Retina , 61 37 байт

r1>`[A-Z]?[a-z]+|[A-Z]+|\d+
_$&
T`L`l

Попробуйте онлайн! (Немного изменен для запуска полного набора тестов.)

объяснение

Вместо того, чтобы находить границы слов для вставки подчеркивания, мы просто сопоставляем каждое слово и добавляем a _. Сопоставление слов слева немного раздражает из-за UUlправила, но, используя сопоставление справа налево в .NET, мы можем легко сопоставить слова жадно. Чтобы избежать лидерства _, мы используем ограничения Retina.

r1>`[A-Z]?[a-z]+|[A-Z]+|\d+
_$&

rАктивирует режим правого на левый, то 1>говорит Retina в процессе все , кроме первого матча (считая слева направо). Тогда есть четыре типа «слова»: Ulll, lll, UUU, ddd. Они легко соответствуют данному шаблону. Подстановка просто записывает _сопровождаемое само слово.

T`L`l

Это просто превращает верхний регистр в нижний регистр, чтобы завершить преобразование.

Мартин Эндер
источник
6

JavaScript (ES6), 79 байт

s=>s.match(/[A-Z]+(?=[A-Z][a-z]|\d|$)|[A-Z]?[a-z]+|\d+/g).join`_`.toLowerCase()
user81655
источник
3

JavaScript (ES6), 89 байт

s=>s.replace(/\d(?=\D)|\D(?=\d)|[a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z])/g,"$&_").toL‌​owerCase()
Нил
источник
2

Powershell, 77 байт

На основании ответа Нейла .

$args-creplace'\d(?=\D)|\D(?=\d)|[a-z](?=[A-Z])|.(?=[A-Z][a-z])','$&_'|% *wer

Менее гольф тестовый скрипт:

$f = {

$args-creplace'\d(?=\D)|\D(?=\d)|[a-z](?=[A-Z])|.(?=[A-Z][a-z])','$&_'|% toLower

}

@(
    ,("Buy24Beers", "buy_24_beers")
    ,("buy24beers", "buy_24_beers")
    ,("MacDonaldAndObrian", "mac_donald_and_obrian")
    ,("MACDonaldAndOBrian", "mac_donald_and_o_brian")
    ,("BigD", "big_d")
) | % {
    $s,$expected = $_
    $result = &$f $s
    "$($result-ceq$expected): $result"
}

Выход:

True: buy_24_beers
True: buy_24_beers
True: mac_donald_and_obrian
True: mac_donald_and_o_brian
True: big_d
Mazzy
источник
1

PowerShell, 68 92 байта

Кратко удалено, +24 байта за неправильное использование RegEx.

($args-creplace'\d(?=\D)|\D(?=\d)|[a-z](?=[A-Z])|.(?=[A-Z][a-z])','$&_').Trim('_').ToLower()

Попробуйте онлайн!

В основном так же, как решения JavaScript.

Габриэль Миллс
источник
Не работает с buy24beersи MACDonaldAndOBrian. Сожалею.
Маззи
1
@ mazzy исправлено, спасибо.
Габриэль Миллс
0

Фактор, 140 байт

[ R/ [a-z][A-Z][a-z]/ [ dup from>> swap dup to>> swap seq>> subseq R/ [A-Z][a-z]/ [ "_" prepend ] re-replace-with ] re-replace-with >lower ]

Ungolfed:

: slice>subseq ( slice -- subseq )
dup from>> swap dup to>> swap seq>> subseq ;

: camel-case>snake-case ( string -- string' )
    R/ [a-z][A-Z][a-z]/ [
        slice>subseq R/ [A-Z][a-z]/
        [ "_" prepend ] re-replace-with
    ] re-replace-with >lower ;
Кот
источник
0

Lua , 135 байт

function snake(s)return s:gsub('%f[^%l]%u','_%1'):gsub('%f[^%a]%d','_%1'):gsub('%f[^%d]%a','_%1'):gsub('(%u)(%u%l)','%1_%2'):lower()end

Попробуйте онлайн!

Это решение использует сокращенную запись Lua для классов символов C (строчные %l, прописные %u, буквенные %a, цифровые %d), граничную запись ( %f[]) и все совпадения, добавляемые в качестве неявного первого захвата в отсутствие других захватов.

cyclaminist
источник