9
\$\begingroup\$

I noticed that in Microsoft Word, single quotations are either or , but not in Notepad. Your task today is: given a string q, convert all the ' characters (only) to or , according to these rules, and then output it:

  • If the character before the quote is a space, and after it comes a character, it becomes
  • If the character before the quote is a letter, and after it is a space, it becomes
  • If the character before and after the quote is a letter, it becomes
  • If the character before and after the quote is a space, it becomes
  • If the quote comes at the beginning it will be , if it comes at the end it becomes
  • If consecutive quotes come one after another, the first 2 become ‘’ and remaining ones become

Test Cases

'Hello'= ‘Hello’ (rules 1 and 2)
'=‘              (rule 5)
H'h=H’h          (rule 3)
 ' = ‘           (rule 4)
'' = ‘’          (rule 6)
a'''b=a‘’’b      (overriding by rule 6)

I'm keeping it this because although it is confusing, it is what the output should be, so if I had to make it more clearer, it will come at the expense of understanding it.

You can assume q contains only upper and lowercase letters, spaces, and quotation marks.

This is , so shortest answer wins!

EDIT: Although in MS Word rule 6 does not override all the other rules, since answers have already been posted that assume this case, I will keep it this way

\$\endgroup\$
8
  • 2
    \$\begingroup\$ Regarding rule #1 "space, and after it comes a character", should it say "after it comes a letter"? \$\endgroup\$
    – Oskar Skog
    Aug 12 at 8:41
  • 4
    \$\begingroup\$ Will rule 6 always override the previous ones? For example, for input a''b, what is expected output? \$\endgroup\$
    – tsh
    Aug 12 at 9:48
  • 1
    \$\begingroup\$ @OskarSkog I believe it means non-whitespace. Otherwise, it would be confuse what should O'_'O become, since _ is neither a space nor a letter. \$\endgroup\$
    – tsh
    Aug 12 at 9:58
  • \$\begingroup\$ @tsh non-whitespace and non-quotemark \$\endgroup\$
    – Oskar Skog
    Aug 12 at 10:11
  • \$\begingroup\$ If input contains only a ', should it become or ? \$\endgroup\$
    – tsh
    Aug 12 at 10:56

6 Answers 6

2
\$\begingroup\$

Retina, 42 bytes

'('+)
‘$.1*’
(^| )'
$1‘
'($|\w)
’$1

Assumes rule 6 takes prio over the other rules.

I have the feeling the first step can be shorter (perhaps with a +^ loop), but couldn't really find anything yet..

Try it online or try it online with </> instead of / so it's a bit more distinguishable).

Explanation:

Replace any sequence of two or more quotes with one opening quote and the rest closing quotes:

'('+)
‘$.1*’

Replace a quote at the start of the string, or a quote with a space before it, with the opening quote:

(^| )'
$1‘

Replace a quote at the end of the string, or a quote with a after it, with the closing quote:

'($|\w)
’$1
\$\endgroup\$
3
  • \$\begingroup\$ Seems like a reasonable assumption \$\endgroup\$
    – mousetail
    Aug 12 at 10:50
  • 1
    \$\begingroup\$ Line 5 looks wrong IMHO. \$\endgroup\$
    – Neil
    Aug 12 at 11:09
  • \$\begingroup\$ @Neil You're completely right, it was wrong! Should be fixed now (although the output remains the same, so the test cases aren't exactly well-covering imo). \$\endgroup\$ Aug 12 at 11:17
1
\$\begingroup\$

Retina 0.8.2, 28 bytes

(?<=^| )'|\b'(?=')
‘
'
’

Try it online! Link includes test cases. Explanation:

(?<=^| )'|\b'(?=')
‘

Quotes become "smart open" quotes at the beginning of the string (by rule 5), after a space (by rules 1, 4 and 6), or after a letter and before a quote (by rule 6).

'
’

All other quotes become "smart close" quotes.

I tried coding the reverse logic by handling "smart close" quotes first but the best I could do was 29 bytes:

(?<=')'|\b'(?!')|'$
’
'
‘

Try it online! Link includes test cases. Explanation: Quotes become "smart close" quotes after quotes (by rule 6), after a letter but not before a quote (by rules 2 and 3), or at the end (by rule 5).

\$\endgroup\$
0
\$\begingroup\$

sed, 109 bytes

:z;s/'''/''’/g;t z;
s/''/‘’/g
s/ '(.)/ ‘\1/g
s/([a-zA-Z])'([a-zA-Z ])/\1’\2/g
s/^'/‘/g
s/'$/’/g

Try it online!

\$\endgroup\$
0
0
\$\begingroup\$

C (clang), 75 bytes

x,o;f(*s){for(x=o=0;*s=*s-39?s[x=0]:8216+x|o&!s[x=1]|o>64&s[1]>64;o=*s++);}

Try it online!

\$\endgroup\$
0
0
\$\begingroup\$

Sed

Here's a shorter version of matteo_c's answer:

:z;s/'''/''’/g;t z;
s/''/‘’/g
s/'/’/g
s/^’/‘/g
s/ ’/ ‘/g
\$\endgroup\$
1
  • 1
    \$\begingroup\$ This is 72 bytes, btw \$\endgroup\$
    – Steffan
    Aug 20 at 20:49
0
\$\begingroup\$

brev, 70 bytes

(strse x "'""’""’(’+)"(conc "‘" (m 1))" ’"" ‘""^’""‘")

Not sure how many bytes this is because Unicode but Steffan kindly counted them and here's the algo:

  1. Replace all ' with ’.
  2. Do "rule six" specially
  3. Replace ^’ and with opens
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Looks like this is 70 bytes (here's a counter). Maybe you could save some by storing the special characters in a variable? \$\endgroup\$
    – Steffan
    Aug 20 at 20:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.