Соглашение о кодировании


22

В этом Coding Golf вы должны преобразовать одно соглашение о кодировании с TitleCase в lower_case_with_underscores. И наоборот!

Спецификация

Замените корпус следующим образом:

  • Если символ подчеркивания является разделителем, измените регистр на Заглавный регистр без разделителя.
  • Если есть несколько слов без разделителя, измените регистр на нижний регистр и добавьте символ подчеркивания в качестве разделителя.
  • В случае только одного слова (или одного символа): измените регистр на Заглавный регистр, если слово начинается со строчной буквы; измените регистр на нижний регистр, если слово начинается с верхнего регистра.

Разрешенные символы:

  • От А до Я
  • от А до Я
  • подчеркивание ( _).

Ввод со смешанными словами запрещен. Примеры запрещенных случаев:

  • Coding_Convention_Conversion
  • a_BC

Примеры случаев

Input                        | Expected Output
===========================================================
CodingConventionConversion   | coding_convention_conversion
coding_convention_conversion | CodingConventionConversion
abc                          | Abc
Abc                          | abc
ABC                          | a_b_c
a_b_c                        | ABC
a                            | A
A                            | a

правила

  • Допускается использовать ToUpper, ToLowerи ToTitleCaseфункции.
  • Использование регулярных выражений разрешено.
  • : выигрывает самый короткий код в байтах!

Использование ToTitleCaseфункции хорошо? Вы не указали, так что я бы предположил, что все в порядке.
Джастин

@Justin: Хороший вопрос действительно. Давайте сделаем это более забавным и запретим функцию ToTitleCase :)
Дариуш Возняк

Черт возьми ... мое решение опирается на это
Джастин

1
@Justin: Хорошо - я не указал это в начале, так что в этом случае - давайте все равно позволим.
Дариуш Возняк

Ответы:


4

Pyth, 25 байтов 29 33 35 40

Сохранено 2 байта благодаря @Dennis

Сохранено 4 байта благодаря @FryAmTheEggman

?rIz0smrd4cz\_tsXzrG1*\_G

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


Ваша ссылка должна быть обновлена.
Исаак

Когда я пытаюсь ввести «abc» в качестве входных данных, он выдает «bc» в качестве выходных данных. Ошибка? :)
Дариуш Возняк

Чтобы исправить то, что заметил @ DariuszWoźniak, вы можете изменить свое состояние с /z\_на rIz0. Я также считаю, что нашел ту же альтернативу программе добавления подчеркиваний: tsXzrG1_Mcj\_G2возможно, кто-то сможет
сыграть в

Ах, нашел это:tsXzrG1*\_G
FryAmTheEggman

8

Джольф, 35 байт

Сохраняет 1 байт благодаря @ Cᴏɴᴏʀ O'Bʀɪᴇɴ . Это закодировано в ISO 8859-7.

? hI'_ΜGI'_dpyH0pxRGIL0"(?=[A-Z])'_

Woohoo моя первая программа Jolf!

объяснение

   // I = input
? hI'_                              // If input contains _
       GI'_                          // Split on _
      Μ    d                         // Loop, then join
            pyH0                     // Make the first character uppercase
                                    // ELSE...
                  RGIL0"(?=[A-Z])    // Split *after* all uppercase chars
                                 '_  // join with _ 
                px                   //Make lowercase

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


Вы можете использовать разделение строк в конце, так что оно становится "(?=[A-Z])'_. Строка закрывается автоматически.
Конор О'Брайен

@ C coolO'Bʀɪᴇɴ о, круто, спасибо!
Даунгейт

7

Сетчатка , 37

Спасибо @ MartinBüttner за сохранение 4 байта!

^|[A-Z]
_$0
T`Ll`lL`_.
^_|_(?=[A-Z])

(Обратите внимание на завершающий символ новой строки.)

Попробуйте онлайн. Обратите внимание, что это включает дополнительную m`настройку пары строк для обработки каждой строки ввода отдельно, поэтому все тестовые случаи могут быть запущены за один раз. Это не является обязательным требованием вопроса, поэтому они не учитываются в баллах.

  • Строки 1 и 2 вставляются _либо в начале ввода, либо перед заглавными буквами. Все слова теперь _разделены, независимо от регистра.
  • Строка 3 меняет регистр первой буквы в каждом слове.
  • Строки 4 и 5 удаляются _либо в начале ввода, либо когда за ними следует заглавная буква.

Это экономит четыре байта: retina.tryitonline.net/…
Мартин Эндер

Также вы можете избежать конечной пустой строки, пропустив последнюю ?=и заменив этот этап на $1(хотя это не влияет на количество байтов).
Мартин Эндер

@ Мартин Очень хорошо - спасибо!
Цифровая травма

5

GNU Sed, 46

Спасибо @TobySpeight за сохранение 2 байта!

Оценка включает +1 для -E(или -r) варианта sed.

s/(^|_)([a-z])/\u\2/g
t
s/[A-Z]/_\l&/g
s/^_//

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

Довольно простой сед:

  • Строка 1 заменяет начало строки или _, а затем строчную букву заглавной буквой этой буквы. gФлаг sвыполняет эту замену для каждого экземпляра найдены
  • tпереходит на :безымянный ярлык, если были найдены совпадения для вышеуказанной замены. Этот ярлык неявно в конце.
  • В противном случае все заглавные буквы заменяются _строчными.
  • Это оставляет ведущий _перед первой буквой. s/^_//удаляет это.

1
@ Тоби Спасибо. -Eработает в моем GNU sed 4.2.2 (Ubuntu 14.04.3), хотя его нет в справочной странице. Я где-то читал [цитата нужна], что -Eэто более новая опция Posix, которая будет официально добавлена ​​в GNU Sed в более новой версии, но уже там неофициально. Независимо от того, -rделает правильные вещи, если -Eне работает для вас.
Цифровая травма

@ Строки 280-282 из sed / sed.c есть /* Undocumented, for compatibility with BSD sed. */ case 'E': case 'r':.
Цифровая травма

@Digital - я ошибся; мой СЭД действительно принимает в -Eкачестве синонима -r. Я не правильно прошел минимальную программу, напримерsed -E -e Q
Тоби Спейт

4

JavaScript (ES6), 87 байт

s=>s.replace(/[A-Z]|(^|_)(.)/g,(c,_,l,i)=>l?l.toUpperCase():(i?"_":"")+c.toLowerCase())

объяснение

В зависимости от того, какая часть регулярного выражения соответствует, оно заменяет совпадение на противоположный случай.

s.replace(
  /[A-Z]|(^|_)(.)/g,
  (c,_,l,i)=>
    l?
      (i?"_":"")+c.toLowerCase()
    :l.toUpperCase()
)

Тестовое задание

var solution = s=>s.replace(/[A-Z]|(^|_)(.)/g,(c,_,l,i)=>l?l.toUpperCase():(i?"_":"")+c.toLowerCase())
<input type="text" id="input" value="coding_convention_conversion" />
<button onclick="result.textContent=solution(input.value)">Go</button>
<pre id="result"></pre>


2

Рубин, 101 87 75 байт

->s{s.gsub(/^.|[A-Z]/,'_\0').gsub(/_./,&:swapcase).gsub(/_(?=[A-Z])|^_/,'')}

К сожалению, это делает то же самое, что и решение Retina, так как этот метод оказался короче всего, что я придумал.


2

Python 3, 130 байт

Быстрая и грязная попытка с помощью регулярных выражений разделить заголовки. Довольно грубая сила: если кто-то может придумать другой подход, я уверен, что это можно победить.

import re
lambda s:('_'.join(re.findall('[A-Z][a-z]*',s)).lower(),''.join([a[0].upper()+a[1:]for a in s.split('_')]))[s.islower()]

2

PHP 160 байт

не самое короткое, но для полноты здесь мое решение в PHP, $ s содержит строку для преобразования:

trim(preg_replace_callback('/((^[a-z]|_[a-z])|([A-Z]))/',function($m){return empty($m[2])?'_'.strtolower($m[3]):strtoupper(str_replace('_','',$m[2]));},$s),'_')

1
Добро пожаловать в Программирование Пазлов и Code Golf Stack Exchange. Хорошо сделано для публикации чего-то на языке, который, как вы знали, не выиграет. Задачи Code-Golf в основном связаны с языками, поэтому использование языка, не связанного с игрой в гольф, хорошо. +1 д: -D
wizzwizz4

1

Perl 6 ,  73 72 71   68 байт

{.comb(/<:Lu><:Ll>*|<:Ll>+/).map({/<:Lu>/??.lc!!.tc}).join('_'x?/<:Lu>/)} # 73
{.comb(/<:Lu><:Ll>*|<:L>+/).map({/<:Lu>/??.lc!!.tc}).join('_'x?/<:Lu>/)}  # 72
{/<:Lu>/??S:g/(^)?(<:Lu>)/{$0||'_'}$1.lc()/!!S:g/[^|_](<:Ll>)/$0.tc()/}   # 71
{.comb(/<:Lu><:Ll>*|<:L>+/).map({/<:Lu>/??.lc!!.tc}).join('_'x!/_/)}      # 68

Использование:

# give it a lexical name
my &code = {...}

for <CodingConventionConversion coding_convention_conversion abc Abc ABC a_b_c a A>
{ say .&code }
coding_convention_conversion
CodingConventionConversion
Abc
abc
a_b_c
ABC
A
a

Объяснение:

{
  .comb( / <:Lu><:Ll>* | <:L>+ / ) # grab the "words" only
  .map({
      /<:Lu>/ # if the word has uppercase
    ??
      .lc     # lowercase the whole word
    !!
      .tc     # otherwise titlecase the word
   })
  .join(  # join the words
    '_'   # with '_'
    x     # repeated
    !/_/  # zero times if it had a _, otherwise once
  )
}

Вы можете быть удивлены, почему я использовал свойства Unicode ( <:Lu>, <:Ll>) вместо просто класса символов. В Perl 6 они больше не пишутся, [a-z]а пишутся, <[a..z]>что в 1,6 раза больше. Скобки [ … ]используются для группирования без захвата, как было написано (?: … )в Perl 5.


1

Japt, 40 байт

UfV="%A" ?UrV@'_s!Y +Xv} :Ur"^.|_."_sJ u

Проверьте это онлайн!

Как это устроено

           // Implicit: U = input string
UfV="%A"   // Set variable V to the string "\\A", and get all matches in U.
?          // If the list is not null:
UrV@     } //  Replace each match X and its index Y with this function:
'_s!Y +Xv  //   Return "_".slice(!Y) (1 for Y=0, 0 for anything else) + X.toLowerCase().
:          // Otherwise:
Ur"^.|_."  //  Replace the char at the beginning and each char following an underscore with:
_sJ u      //   The last char of the match (the letter) .toUpperCase().

1

Perl 5, 42 байта

40 байтов плюс 2 за -p(спасибо, dev-null )

s/[A-Z]/_\l$&/g||s/(^|_)(.)/\u$2/g;s/_//

В Windows, используя Perl и MINGW32, я не получаю вывод, что мне не хватает?
ChatterOne

@ChatterOne Я не знаю, что такое MINGW32, но он отлично работал на Strawberry Perl. Используйте -Eвместо -e.
msh210

1

𝔼𝕊𝕄𝕚𝕟 3, 15 символов / 32 байта (неконкурентный)

⟮ѨDZï⟯≠ï?Ⅰ:ѨȎѨƎï

Try it here (Firefox only).

v3 был выпущен после этой проблемы, с кучей исправлений и обновлений библиотеки.

объяснение

Это просто коллаж из встроенных.

⟮ѨDZï⟯≠ï?Ⅰ:ѨȎѨƎï // implicit: ï=input
⟮ѨDZï⟯≠ï?        // check if ï is NOT in snake_case
       Ⅰ       // if so, then convert to snake_case
        :ѨȎѨƎï // otherwise, convert to camelCase and make the first letter UPPERCASE


1

Python 3 , 86 байт

lambda s,u='_':''.join([u[i>u:]+i.lower()for i in(s<u)*s]or[u]+s.title().split(u))[1:]

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

Также работает в Python 2 .

Воспользовавшись удобным фактом, что значение ascii для _(95) находится прямо между значениями прописных (65-90) и строчных (97-122) букв, что позволяет легко сравнивать строки.


1

Forth (gforth) , 129 байтов

: f bounds dup c@ 32 xor emit 1+ ?do i c@ '_ < if ." _"i c@ 32 + emit then i c@ '_ > if i 1- c@ '_ = 32 * i c@ + emit then loop ;

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

Код Объяснение

: f              \ start a new word definition
  bounds         \ convert string address and length to beginning and ending address
  dup c@         \ get the first character
  32 xor emit    \ convert to the opposite case and output
  1+             \ add 1 to beginning of string (skip starting char)
  ?do            \ begin counted loop over string character addresses
    i c@ '_ <    \ check if char is uppercase 
    if           \ if it is:
      ." _"      \ output underscore
      i c@       \ get current char
      32 + emit  \ convert to lowercase and output
    then         \ end if block
    i c@ '_ >    \ check if lowercase (not '_')
    if           \ if it is:
      i 1- c@    \ get the previous character
      '_ = 32 *  \ if it's an underscore, multiply by 32 (true = -1 in forth)
      i c@ +     \ add result to current char (make uppercase if previous was '_')
      emit       \ output resulting char
    then         \ end if block
  loop           \ end loop
;                \ end word definition
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.