# Convert a string to sentence case

Input:

A string (or the closest thing to that in your language)

Output:

The same string but converted to sentence case

Rules:

• For this challenge, sentence case can be considered "The first letter of each sentence is capitalized. The rest are lowercase." (i.e. proper nouns do not have to be capitalized)
• If the input does not include a period, it is treated as one sentence.
• The other 2 punctuation marks used to end a sentence in english (? and !) can be considered periods
• If a letter immediately follows a punctuation mark the same rules still apply (i.e. the first letter is capitalized and all following letters are lowercased until the next punctuation mark)

Sample test cases:

"hello world." // "Hello world."

"CODEGOLF IS FUN." // "Codegolf is fun."

"no period" // "No period"

"the ball was red. so was the balloon." // "The ball was red. So was the balloon."

"I love codegolf.stackexchange.com" // "I love codegolf.Stackexchange.Com"

"heLLo! hOW are yOU toDay? hOpEfulLy yOu are okay!" // "Hello! How are you today? Hopefully you are okay!"


This is , so the shortest code wins!

• Suggested test case: “Everybody loves codegolf.stackexchange.com !!! ♡ 4 golf”. May 16 '20 at 0:20
• All other punctuation marks - so ", ', ,, ;, -, ...? May 16 '20 at 2:52
• You wouldn't normally capitalize a sentence after every ", ', ,, ;, -. The challenge is to convert to standard sentence case May 16 '20 at 15:36
• @Lebster I'll vote to re-open if you specify exactly which punctuation marks can end a sentence (if it's just ., ? and ! then remove the word "etc." since it adds ambiguity). A few more test cases would also be very helpful May 16 '20 at 21:19
• It should also be specified what happens if there is a letter immediately after a period, or if that's even possible May 17 '20 at 10:23

# 05AB1E, 3 bytes

l.ª


Try it online!

Nothing like a good old built-in answer! This converts the string to lowercase and then performs sentence case.

# Erlang (escript), 77 bytes

If non-periods are allowed... well, that greatly golfs my program!

g(H)->[string:titlecase(string:lowercase(I))||I<-re:split(H,"(\\W[\\W ]+)")].


Try it online!

## Explanation

g(H)->                      % Define a function.

re:split(H,"(\\W[\\W ]+)")  % Split the operand on "sentences", keeping the items reserved for splitting.

% I.e. none of the items from the string is missing after the split

||I<-   ]                   % For every item in a sentence,
[string:titlecase(string:lowercase(I))

%     Title case the sentence.
.                           % End the function.


# JavaScript (Node.js), 101 bytes

s=>(s.reduce((a,c)=>c=='.'?(r+=c,'Upp'):c>' '?(r+=c['to'+a+'erCase'](),'Low'):(r+=c,a),'Upp',r=''),r)


Try it online!

# Retina, 13 bytes

.+
$T \b .$L


Try it online!

## Explanation

General approach is to convert every word to title-case, then un-convert the words that shouldn't have been converted

.+ Matches the entire string, $T converts it to title case (every word lowercase with an uppercase first character \b . - \b Matches the position between a word-character and a non-word character (i.e. the end of a word without a full stop) followed by a space and any other character . $L converts this to lowercase

# perl -p, 33 bytes

$_=lc=~s/(^|\pP)\s*\K\pL/uc$&/erg


Try it online!

This lowercases the string, then upper cases any letter following either the beginning of the string, or after a punctuation character (skipping any whitespace in between). This does turn a string "foo, bar, baz" into "Foo, Bar, Baz", but that's how I read the requirement about all punctuation.

• You can save two bytes by making the lc and the substitution separate statements. Try it online! May 18 '20 at 6:18

# C (gcc), 80 $$\\cdots\$$ 87 76 bytes

Added 13 bytes to fix a bug kindly pointed out by Abigail.

c;b;f(char*s){for(b=1;c=*s;b|=ispunct(c))*s++=isalpha(c)?b?b=0,c&95:c|32:c;}


Try it online!

How

Capitalises the first letter and every letter after a punctuation mark. Every other letter is converted to lower case. Simply prints everything else.

• This fails on the amount is $15. Regardless of whether you interpret $ as a punctuation character, the 1 should remain as is, it being its own uppercase. May 17 '20 at 11:38
• @Abigail Oops, wasn't dealing with numeric chars. Fixed now - thanks! :-) May 17 '20 at 13:15

# Python 3, 67 bytes

-7 bytes thanks to Surculose Sputum

If other punctuation like ! or ? are allowed.

lambda s:re.sub(r'\w[\w ]+',lambda x:x[0].capitalize(),s)
import re


Try it online!

# Python 2, 53 bytes

lambda s:'. '.join(map(str.capitalize,s.split('. ')))


Try it online!

• 67 bytes in Python 3, since you can use x[0] instead of x.group(0). May 16 '20 at 1:56
• @SurculoseSputum I wasn't aware of that trick. Thanks! May 16 '20 at 2:14

# Retina 0.8.2, 19 bytes

TLl
TlL^.|\W .


Try it online! Link includes test cases. Explanation:

TLl


Lowercase everything.

TlL^.|\W .


Uppercase the first character and any character that follows a non-word character and a space. It might not be the world's best heuristic but it works on the test case.

# Red, 81 bytes

func[s][parse lowercase s[any[any" "p: change skip(p/1 - 32)thru["."|"!"|"?"]]]s]


Try it online!

# Vim, 20 19 bytes

Saved 1 byte by using ~ to toggle casing instead of vU.

v$uqq~/[.!?] w@qq@q  Try it online! Explanation: v$u                 # Selects whole line and changes it to lowercase
qq               # Starts recording macro q
~              # Toggles uppercase on current character
/[.!?]        # Jumps to next . ! or ?
w       # Jumps to next non-whitespace character
@q     # Calls macro q recursively
q@q  # Ends macro q and calls it