编码约定转换


22

在那个Coding Golf中,您应该将TitleCase的一种编码约定转换为lower_case_with_underscores。而且...反之亦然!

规格

通过以下方式更改外壳:

  • 如果下划线字符是定界符,则将大小写更改为没有任何定界符的标题大小写。
  • 如果有多个没有分隔符的单词,请将大小写更改为小写并添加下划线字符作为分隔符。
  • 如果只有一个单词(或一个字符):如果单词以小写字母开头,则将大小写更改为“标题大小写”;如果单词以大写字母开头,请将大小写更改为小写。

允许的字符:

  • 从A到Z
  • 从a到z
  • 下划线(_)。

不允许输入大小写混合的单词。不允许的案例示例:

  • 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

规则

  • 它被允许使用ToUpperToLowerToTitleCase功能。
  • 允许使用正则表达式。
  • :以字节为单位的最短代码胜出!

使用ToTitleCase功能可以吗?您没有指定,所以我认为可以。
贾斯汀

@贾斯汀:确实是个好问题。让我们把更多的乐趣,并禁止该ToTitleCase功能:)
达留沃兹尼亚克

该死...我的解决方案依靠它
贾斯汀

1
@Justin:好的-我一开始没有指定它,所以在这种情况下-还是允许它。
DariuszWoźniak'16

Answers:


4

Pyth,25个字节29 33 35 40

@Dennis节省了2个字节

@FryAmTheEggman节省了4个字节

?rIz0smrd4cz\_tsXzrG1*\_G

在线尝试


您的链接需要更新。
isaacg '16

当我尝试将“ abc”作为输入时,它将产生“ bc”作为输出。虫子?:)
DariuszWoźniak'16

要解决@DariuszWoźniak注意的问题,可以将条件从更改/z\_rIz0。我也相信我找到了与下划线程序相同长度的替代方法:tsXzrG1_Mcj\_G2,也许有人可以打更多的高尔夫球……
FryAmTheEggman

啊,找到了:tsXzrG1*\_G
FryAmTheEggman,2016年

8

Jolf,35个字节

由于@CᴏɴᴏʀO'Bʀɪᴇɴ保存了1个字节。这是在ISO 8859-7中编码的。

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

哇,我的第一个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ᴏɴᴏʀO'Bʀɪᴇɴ哦,太好了,谢谢!
Downgoat

7

视网膜,37

感谢@MartinBüttner节省了4个字节!

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

(请注意尾随换行符。)

在线尝试。 注意,这包括m`配置两行以分别处理每条输入线的额外功能,因此所有测试用例都可以一次性运行。这不是问题的要求,因此这些不计入分数。

  • 第1行和第2行在_输入的开头或大写字母之前插入。现在_,所有单词都被分隔,无论大小写如何。
  • 第3行交换每个单词中第一个字母的大小写。
  • 第4行和第5行在_输入开始时或大写字母后删除。

:这样可以节省四个字节retina.tryitonline.net/...
马丁安德

您也可以通过省略最后一个?=阶段并将其替换为$1(但不影响字节数)来避免尾随空行。
Martin Ender

@Martin非常好-谢谢!
Digital Trauma

5

GNU Sed,46岁

感谢@TobySpeight节省了2个字节!

得分包括的+1 -E(或-r)选项sed

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

在线尝试。

相当简单的sed:

  • 第1行用或开头_,后接小写字母和大写字母。对找到的每个实例执行此替换的g标志s
  • t:如果上述替换项匹配,则跳转到未命名的标签。该标签隐式地位于末尾。
  • 否则,所有大写字母都将替换_为该字母的小写字母
  • 这样_就在第一个字母之前留下了一个前导。 s/^_//删除。

1
@Toby谢谢。 -E可在我的GNU sed 4.2.2(Ubuntu 14.04.3)中使用,尽管不在手册页中。我在某处[需要引用]中读到了-E较新的Posix选项,该选项将在较新的版本中正式添加到GNU Sed中,但是已经非正式地存在了。无论如何,-r如果-E对您不起作用,那就做对了。
Digital Trauma

sed / sed.c的 @Toby 行280-282/* Undocumented, for compatibility with BSD sed. */ case 'E': case 'r':
Digital Trauma

@Digital-我误会了;我的sed 接受-E作为一个代名词-r。我没有正确通过最小程序,例如sed -E -e Q
Toby Speight

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

Ruby,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。用您知道不会赢的语言发布的东西做得很好。代码高尔夫的挑战大部分都存在于语言中,因此使用非高尔夫语言是很好的。+1 d:-D
wizzwizz16年

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 '16

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中使用

利用方便的事实,即_(95)的ascii值恰好介于大写(65-90)和小写(97-122)字母之间,这使得可以轻松进行字符串比较。


1

第四(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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.