[Question]
  [
In that Coding Golf, you should convert one coding convention with TitleCase to lower\_case\_with\_underscores. And... vice versa!
# Specification
Change the casing in a following way:
* If underscore character is a delimiter, change the casing to Title Case without any of delimiter.
* If there are multiple words with no delimiter, change the casing to lower case and add an underscore character as a delimiter.
* In case of only one word (or one character): change the casing to Title Case if the word starts with lower case; change the casing to lower case if the word starts with the upper case.
Allowed characters:
* A to Z
* a to z
* underscore (`_`).
Input with mixed cased words are disallowed. Examples of disallowed cases:
* `Coding_Convention_Conversion`
* `a_BC`
# Example Cases
```
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
```
# Rules
* It is allowed to use `ToUpper`, `ToLower` and `ToTitleCase` functions.
* Using regular expressions is allowed.
* [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"): shortest code in bytes wins!
  
[Answer]
# Jolf, 35 bytes
*Saves 1 byte thanks to @C·¥è…¥·¥è Ä O'B Ä…™·¥á…¥*. This is encoded in ISO 8859-7.
```
? hI'_ŒúGI'_dpyH0pxRGIL0"(?=[A-Z])'_
```
Woohoo my first Jolf program!
## Explanation
```
   // 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
```
[Try it online](http://conorobrien-foxx.github.io/Jolf/#code=PyBoSSdfEM6cR0knX2RweUgwcHhSR0lMMCIoPz1bQS1aXSknXw)
[Answer]
# [Retina](https://github.com/mbuettner/retina), 37
Thanks to @ MartinB√ºttner for saving 4 bytes!
```
^|[A-Z]
_$0
T`Ll`lL`_.
^_|_(?=[A-Z])
```
(Note the trailing newline.)
[Try it online.](http://retina.tryitonline.net/#code=bWBefFtBLVpdCl8kMApUYExsYGxMYF8uCm1gXl98Xyg_PVtBLVpdKQo&input=Q29kaW5nQ29udmVudGlvbkNvbnZlcnNpb24KY29kaW5nX2NvbnZlbnRpb25fY29udmVyc2lvbgphYmMKQWJjCkFCQwphX2JfYwphCkE) Note this includes extra `m``  to configure a couple of lines to treat each input line separately so all testcases may be run in one go. This is not a requirement of the question, so these are not counted in the score.
* Lines 1 and 2 insert `_` either at the beginning of input or before uppercase letters. All words are now `_`-separated, regardless of case.
* Line 3 swaps case of the first letter in each word.
* Lines 4 and 5 remove `_` either at the start of input, or when followed by an uppercase letter.
[Answer]
# GNU Sed, 46
Thanks to @TobySpeight for saving 2 bytes!
Score includes +1 for `-E` (or `-r`) option to `sed`.
```
s/(^|_)([a-z])/\u\2/g
t
s/[A-Z]/_\l&/g
s/^_//
```
[Try it online.](https://ideone.com/MqSbzl)
Fairly straightforward sed:
* Line 1 substitutes beginning of line or `_`, followed by a lowercase letter with the upper case of that letter. The `g` flag to `s` performs this substitution for each instance found
* `t` jumps to the `:` unnamed label if there were any matches for the above substitution. This label is implicitly at the end.
* Otherwise all uppercase letters are substituted with `_` the lower case of that letter
* This leaves a leading `_` before the first letter. `s/^_//` removes that.
[Answer]
# Pyth, 25 bytes ~~29 33 35 40~~
*Saved 2 bytes thanks to @Dennis*
*Saved 4 bytes thanks to @FryAmTheEggman*
```
?rIz0smrd4cz\_tsXzrG1*\_G
```
[Try it online](http://pyth.herokuapp.com/?code=%3FrIz0smrd4cz%5C_tsXzrG1%2a%5C_G&input=CodingConventionConversion&test_suite=1&test_suite_input=CodingConventionConversion%0Acoding_convention_conversion%0Aabc%0Aa_b_c%0AABC&debug=0)
[Answer]
# JavaScript (ES6), 87 bytes
```
s=>s.replace(/[A-Z]|(^|_)(.)/g,(c,_,l,i)=>l?l.toUpperCase():(i?"_":"")+c.toLowerCase())
```
## Explanation
Depending on which part of the regex matched, it replaces the match with the opposite case.
```
s.replace(
  /[A-Z]|(^|_)(.)/g,
  (c,_,l,i)=>
    l?
      (i?"_":"")+c.toLowerCase()
    :l.toUpperCase()
)
```
## Test
```
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>
```
[Answer]
# PHP 160 bytes
not the shortest but for completeness here my solution in PHP, $s holds the string to convert:
```
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),'_')
```
[Answer]
# Ruby, ~~101~~ ~~87~~ 75 bytes
```
->s{s.gsub(/^.|[A-Z]/,'_\0').gsub(/_./,&:swapcase).gsub(/_(?=[A-Z])|^_/,'')}
```
Unfortunately, this does exactly the same thing as the Retina solution, as that method ended up being shorter than anything else I came up with.
[Answer]
# Python 3, 130 bytes
Quick and dirty attempt using regex to split at the caps. Pretty brute force: if anyone can come up with a different approach I'm sure this can be beaten.
```
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()]
```
[Answer]
# ùîºùïäùïÑùïöùïü 3, 15 chars / 32 bytes (noncompetitive)
```
‚üÆ—®«±√Ø‚üØ‚â†√Ø?‚Ö†:—®»é—®∆é√Ø
```
`[Try it here (Firefox only).](http://molarmanful.github.io/ESMin/interpreter3.html?eval=false&input=CodingConventionConversion&code=%E2%9F%AE%D1%A8%C7%B1%C3%AF%E2%9F%AF%E2%89%A0%C3%AF%3F%E2%85%A0%3A%D1%A8%C8%8E%D1%A8%C6%8E%C3%AF)`
v3 was released after this challenge, with a bunch of bugfixes and library updates.
# Explanation
This is just a mashup of builtins.
```
‚üÆ—®«±√Ø‚üØ‚â†√Ø?‚Ö†:—®»é—®∆é√Ø // implicit: √Ø=input
‚üÆ—®«±√Ø‚üØ‚â†√Ø?        // check if √Ø is NOT in snake_case
       ‚Ö†       // if so, then convert to snake_case
        :—®»é—®∆é√Ø // otherwise, convert to camelCase and make the first letter UPPERCASE
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 24 bytes
```
e‚Ç¨√òA·∏äk≈ílj‚Äù_$ ã‚Åæ_ y≈ít·∏≤∆≤}·∫∏?
```
[Try it online!](https://tio.run/##y0rNyan8/z/1UdOawzMcH@7oyj46KSfrUcPceJVT3Y8a98UrVB6dVPJwx6Zjm2of7tph/9/6UcMcBV07BaAS68PtXIfbgToj//9Xcs5PycxLd87PK0vNK8nMzwOzioqBLCUdpWSwZHwyXBbChEnnJeamAik/EAUA "Jelly ‚Äì Try It Online")
[Answer]
# [Python 3](https://docs.python.org/3/), 86 bytes
```
lambda s,u='_':''.join([u[i>u:]+i.lower()for i in(s<u)*s]or[u]+s.title().split(u))[1:]
```
[Try it online!](https://tio.run/##hc1NCsIwEAXgfU4x0MUkKgVxV1TQHqOWktZWR2pS8qN4@hojuKvNJg/m473h5a5abcZudxp7ea/PEuzK77DCDDG9aVK88AXtfVYuKe31szVcdNoAQTjZrRcLW2pT@HJpU0eub7lI7dCT416IYp2V40fboIEzzPWZ1CXX6tEqR1rFZGxIuAKABJoIquYnvjEShv@uoSCB6X6Gsm7iyMRL4FA3DA9zSkZ1zGdUVVfBxW9ahs1jHtS/rqjC4pyRTGQwGFKOd9wKMb4B "Python 3 ‚Äì Try It Online")
Also [works in Python 2](https://tio.run/##hc1NCsIwEAXgfU4x0MUkKgVdFhW0x6ilpLXVkZqU/CievsYI7mqzyYP5eG94uatWm7HbncZe3uuzBLvyO6wwQ0xvmhQvfEF7n5VLSnv9bA0XnTZAEE5268XCltoUvlza1JHrWy5SO/TkuBeiWGfl@NE2aOAMc30mdcm1erTKkVYxGRsSrgAggSaCqvmJb4yE4b9rKEhgup@hrJs4MvESONQNw8OcklEd8xlV1VVw8ZuWYfOYB/WvK6qwOGckExkMhpTjHbdCjG8).
Making use of the convenient fact that the ascii value for `_` (95) is right in between those of the uppercase (65-90) and lowercase (97-122) letters, which allows for easy string comparisons.
[Answer]
# [Perl 6](http://perl6.org), ~~¬†73¬†72¬†71¬†~~¬†68 bytes
```
{.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
```
### Usage:
```
# 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
```
### Explanation:
```
{
  .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
  )
}
```
You may be wondering why I used the Unicode properties (`<:Lu>`, `<:Ll>`) instead of just a character class. 
In [Perl 6](http://perl6.org) they are no longer spelled `[a-z]` they are spelled `<[a..z]>` which is 1.6 times as big.
The brackets `[¬†‚Ä¶¬†]` are used for non-capturing grouping instead which was spelled as `(?:¬†‚Ä¶¬†)` in Perl¬†5.
[Answer]
# Japt, 40 bytes
```
UfV="%A" ?UrV@'_s!Y +Xv} :Ur"^.|_."_sJ u
```
[Test it online!](http://ethproductions.github.io/japt?v=master&code=VWZWPSIlQSIgP1VyVkAnX3MhWSArWHZ9IDpVciJeLnxfLiJfc0ogdQ==&input=ImFfYl9jIg==)
# How it works
```
           // 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().
```
[Answer]
# Perl 5, 42 bytes
40 bytes plus 2 for `-p` (thanks, [dev-null](/u/48657))
```
s/[A-Z]/_\l$&/g||s/(^|_)(.)/\u$2/g;s/_//
```
[Answer]
# [Forth (gforth)](http://www.complang.tuwien.ac.at/forth/gforth/Docs-html/), 129 bytes
```
: 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 ;
```
[Try it online!](https://tio.run/##jc5NDoIwEAXgvad4YWMiwUTcGFH84SANlIJNtNPQavT0SAsaN6LddKb9Mm8qauwpqit3te0aFQq6qtKgvGrwPZYx7tRAXKTFIsSuJEj3PmXYQFaYB2CBHGTYO3sS6q1SpyQW0dBvHZz135/@TKSRdBtoxC7bPrTwS8QrRMgLA6NzLoxLRJQi6FblDZKJCZBRKVWdkboJZSUpXzWmqzoL7Qj3hPG36csBeZIX3PEvx5PDH@SY/SI5K9j3OT0ZmfEKGiftEw "Forth (gforth) ‚Äì Try It Online")
### Code Explanation
```
: 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
      
```
[Answer]
# [Pip](https://github.com/dloscutoff/pip), 37 bytes
```
'_Na?UC@_.@>_Ma^'_(LC_MRXU.XL.'+a)J'_
```
[Try it online!](https://tio.run/##K8gs@P9fPd4v0T7U2SFez8Eu3jcxTj1ew8c53jcoIlQvwkdPXTtR00s9/v///875KZl56c75eWWpeSWZ@XlgVlExkAUA "Pip ‚Äì Try It Online")
Lot of underscores in this one.
[Answer]
# [K (ngn/k)](https://bitbucket.org/ngn/k), 43 bytes
```
{("_"/(&x<_x)__x;,/`c$t-32*~<'t:"_"\x)x~_x}
```
[Try it online!](https://tio.run/##PYnRCoJAEEX/ZYjaLUWwN9cX298IJl1TRJgFW2Ig8te3UbGXw7n3jCn1FGNXfBQgZOrIJbJGZJNkD3cI6TU/z@UpFFLvrHlG/saLCqaTT4H17UC99fR@Uhg8rTa9xMCAWyO6f910z3XjhNXGm10ebFBWAvWCCrSOPw "K (ngn/k) ‚Äì Try It Online")
* `x~_x` check if the input `x` is all lowercase
* `(...;...)` index into this two-item list depending on that value (i.e., return the first item in the list if `x` contains an uppercase letter, and the second item if it does not)
* When `x` contains an uppercase letter:
	+ `(&x<_x)` identify indices of uppercase letters
	+ `(...)__x` split the lowercased input on those indices
	+ `"_"/` join the resulting chunks with underscores
* When `x` is all lowercase:
	+ `t:"_"\x` split input on underscores, storing in variable `t`
	+ `t-32*~<'t` capitalize the first letter in each chunk (this converts to integers)
	+ `,/`c$` convert back to characters, flattening the list
[Answer]
# Japt, 37 bytes
```
a'_ √Ñ?Uq'_ ¬ÆhZu g} q:U√≤@Yc <#a} q'_ v
```
[Try it online!](https://ethproductions.github.io/japt/?v=1.4.6&code=YSdfIMQ/VXEnXyCuaFp1IGd9IHE6VfJAWWMgPCNhfSBxJ18gdg==&input=WyJIZWxsb1RoZXJlIiwKImhlbGxvX3RoZXJlIl0KLW0=)
Explanation:
```
There are some unicode chars that a shortcuts for common groups of chars,
like √Ñ is +1. This is the expanded version.
     // U = input string
a'_  // get index of "_" in string, -1 if not found
+1   // add 1 to make -1 falsy
?    // if truthy, ie. if there is an underscore in the input text
Uq'_ // split on underscores
m_   // map
h    // replace character (first char by default)
Zu g // the first letter of the string converted to uppercase (Zug)
} q  // close function and join
:    // else, ie. the string doesn't have any underscores
U√≤   // runs func on every pair of chars, splits them if it returns true
@Yc <#a } // returns true if the second char code is less than "a", ie. uppercase
q'_  // join with underscores
v    // make lowercase
implicit print
```
First Japt program, I beat the creator, and Zu g!
[Answer]
# [Japt](https://github.com/ETHproductions/japt), ~~27~~ 26 [bytes](https://en.wikipedia.org/wiki/ISO/IEC_8859-1)
I fear I may have gone in the wrong direction with this; stuck on 27 and can't seem to do any better.
```
r"^.|_.|%A"√à√åc^H i'_pY¬©X√äu
```
[Try it](https://petershaggynoble.github.io/Japt-Interpreter/?v=1.4.6&code=ciJeLnxfLnwlQSLIzGNeSCBpJ19wWalYynU&input=WwoiQ29kaW5nQ29udmVudGlvbkNvbnZlcnNpb24iCiJjb2RpbmdfY29udmVudGlvbl9jb252ZXJzaW9uIgoiIgoiYWJjIgoiQWJjIgoiIgoiQUJDIgoiYV9iX2MiCiIiCiJhIgoiQSIKXQotbVI)
```
r"^.|_.|%A"√à√åc^H i'_pY¬©X√äu     :Implicit input of string
r                              :Replace
 "^.|_.|%A"                    :RegEx /^.|_.|[A-Z]/g
           √à                   :Pass each match X at 0-based index Y through the following function
            √å                  :  Last character of X
             c                 :  Charcode
              ^H               :  Bitwise XOR with 32
                 i             :  Prepend
                  '_p          :    "_" repeated
                     Y¬©        :      Logical AND of Y and
                       X√ä      :      Length of X
                         u     :      Mod 2
```
]