17
\$\begingroup\$

Given a string, replace all left-double-quotes into two backticks and all right-double-quotes into two single-quotes.

Left-quotes means the quotes that starts a quote. Right-quotes means the quotes that ends a quote. Quotes cannot be nested. You may assume that there are an even number of double-quotes in the string.

Examples

Input:

"To be or not to be," quoth the Bard, "that
is the question".
The programming contestant replied: "I must disagree.
To `C' or not to `C', that is The Question!"

Output:

``To be or not to be,'' quoth the Bard, ``that
is the question''.
The programming contestant replied: ``I must disagree.
To `C' or not to `C', that is The Question!''
\$\endgroup\$
  • \$\begingroup\$ What are left double quotes and right double quotes? \$\endgroup\$ – someone Aug 24 at 7:35
  • 1
    \$\begingroup\$ @someone Left double quotes are the quotes that begins a quote. Right double quotes are the quotes that ends a quote. \$\endgroup\$ – HighlyRadioactive Aug 24 at 7:36
  • \$\begingroup\$ Can quotes be nested? \$\endgroup\$ – someone Aug 24 at 7:38
  • \$\begingroup\$ @someone Nope. They can't. \$\endgroup\$ – HighlyRadioactive Aug 24 at 7:39
  • 2
    \$\begingroup\$ @LegionMammal978 "Can quotes be nested?" ... "@someone Nope. They can't." \$\endgroup\$ – Jonathan Allan Aug 24 at 22:56

25 Answers 25

18
\$\begingroup\$

Unreadable, 789 777 bytes

-12 bytes by using variable X34 rather than X6.

'""""""'""'"""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'"""'""""""'""'""'""'""'"""'""'""'""'""'""'"""""""'""'"""'"""""'""'""""""'"""'""""""""""'""""'""""""'""'""'""'"""'"""""""'""'"""'""""'""""""'""'""'"""'"""""""'"""'""""'"""""'"""""""'""'""'""'"""'""""'""""""'""'""'""'"""'""""""""'"""""""'""'""'""'"""'""""""'""'""'"""'""""""""'"""""""'""'""'"""'"""""""""'"""""""'""'""'"""'"'"""""""'"""'"'"""""""""'"""""""'"""""""'""'"""'""""'""""""'"""""""'""'"""'""""""""'"""'"'"""""""'""'""'""'""'"""'""""'""""""'"""""""'""'"""'"""'"'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'"""""""'""'""'""'""'"""

Try it online!

Displayed in variable-width font, per the traditional tribute to the language name.

I learnt Unreadable for this challenge, because it is obviously the best tool for the job. The only characters allowed in Unreadable are ' and ", so surely it is perfectly suited to a challenge which involves changing " into ''. Isn't it?

Explanation:

'""""""'""'""" assign to X2
'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""" 34 (double quote sign)
'""""""'""'""'""'""'""" assign to X5
'""'""'""'""'""'"""""""'""'""" X2+5 (apostrophe sign)
'"""""'""'""""""'"""'"""""""""" while (1+ (assign to X1 a value read from stdin, or -1 if stdin is empty) != 0)
 '"""" do 2 things
 '""""""'""'""'""'""" assign to X4
 '"""""""'""'""" the value of X2
 AND
 '"""" do 2 things
 '""""""'""'""'""" assign to X3
 '"""""""'""" the value of X1
 AND
 '"""" do 2 things
 '"""""'"""""""'""'""'""'""" while(X4 != 0)
  '"""" do 2 things
  '""""""'""'""'""'""" assign to X4
  '""""""""'"""""""'""'""'""'""" X4-1
  AND
  '""""""'""'""'""" assign to X3
  '""""""""'"""""""'""'""'""" X3-1
 end while
 AND
 '"""""""""'"""""""'""'""'""" if(X3 != 0)
  '"'"""""""'""" print X1
 else
  '" print the output of
  '"""""""""'"""""""'"""""""'""'""" if(X34 !=0)
   '"""" do 2 things
   '""""""'"""""""'""'"""'""""""""'""" assign X34=0
   AND
   '"'"""""""'""'""'""'""'""" print X5
  else
   '"""" do 2 things
   '""""""'"""""""'""'"""'""" assign X34=1
   AND
   '"'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'"""""""'""'""'""'""'""" print X5+57
 end if
end while

(Calls to X34 are actually calls to X(X5), since X5=34.)

\$\endgroup\$
  • 1
    \$\begingroup\$ A quoty language in a quoty challenge LOL \$\endgroup\$ – HighlyRadioactive Aug 27 at 9:45
5
\$\begingroup\$

Retina, 13 bytes

Learning Retina quickly because for some reason I don't like Japt winning and feel like a C# solution would use regular expressions anyway. I know there is a Retina answer, but I haven't used it when creating this, and I found it (exactly) too anyway.

#2$`"
``
"
''

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ Why the hate for Japt?! :p \$\endgroup\$ – Shaggy Aug 24 at 13:11
5
\$\begingroup\$

JavaScript (ES9), 34 bytes

Working on quoted blocks:

s=>s.replace(/"(.*?)"/gs,"``$1''")

Try it online!


JavaScript (ES6), 38 bytes

Working on each double-quote separately:

s=>s.replace(/"/g,_=>(c="'`"[s^=1])+c)

Try it online!

\$\endgroup\$
  • \$\begingroup\$ dotAll flag for RegExp is new feature of ECMAScript 2018, not included in ES6. \$\endgroup\$ – tsh Aug 26 at 2:10
  • \$\begingroup\$ @tsh Good catch. Updated. \$\endgroup\$ – Arnauld Aug 26 at 9:11
4
\$\begingroup\$

Jelly, 15 13 bytes

⁾``⁾''2ƭ”"Ƒ¡€

Try it online!

Full program.

\$\endgroup\$
4
\$\begingroup\$

Python 3, 65 bytes

f=lambda s:s and(s[0],"`'"[s.count('"')%2]*2)[s[0]=='"']+f(s[1:])

Try it online!

-8 bytes thanks to Erik the Outgolfer

\$\endgroup\$
  • \$\begingroup\$ As for the second function, you can remove 8 bytes (it's not as different as it may seem, I just replaced the s[0].replace with an explicit s[0]=='"' check, along with some other modifications). \$\endgroup\$ – Erik the Outgolfer Aug 24 at 13:08
  • \$\begingroup\$ @EriktheOutgolfer Nice finds, thanks! \$\endgroup\$ – Jitse Aug 24 at 13:42
4
\$\begingroup\$

Japt, 12 bytes

Would be 11 only for a limitation of (or maybe it's a bug in) Japt.

r'"ȲîT°g"`'

Try it

r'"ȲîT°g"`'     :Implicit input of string
r'"              :Replace double quotes
   È             :Pass each match through a function
    ²            :  Duplicate
     î           :  Replace each character with
      T°         :    Postfix increment T (initially 0)
        g"`'     :    Index into "`'" with wrapping
\$\endgroup\$
  • \$\begingroup\$ It's too bad you can't use Q here :\ \$\endgroup\$ – Oliver Aug 26 at 19:56
  • \$\begingroup\$ @Oliver, I can (and I originally did); I'd just need a , too. \$\endgroup\$ – Shaggy Aug 26 at 20:07
  • \$\begingroup\$ I mean it's too bad you couldn't simply use Q in place of '" \$\endgroup\$ – Oliver Aug 26 at 20:11
4
\$\begingroup\$

TeX, 54 32 bytes

For a TeX quotes replacement challenge we also need a TeX version of course!

\catcode`"13\def"#1"{``#1''}...\bye

... is the input string, so it doesn't add to the byte count.

\$\endgroup\$
  • 1
    \$\begingroup\$ Why not the simpler \def"#1"{``#1''}? (or \long\def if you expect a quote to cross a paragraph boundary) \$\endgroup\$ – Phelype Oleinik Aug 26 at 10:11
  • 1
    \$\begingroup\$ For the obvious reason that I didn't think of that :-) \$\endgroup\$ – siracusa Aug 26 at 19:47
2
\$\begingroup\$

Charcoal, 23 bytes

WS⊞υι⭆⪪⪫υ¶¦"⎇κ⁺ײ§'`κιι

Try it online! Link is to verbose version of code. Includes 8 bytes to avoid a cumbersome input format. Explanation:

WS⊞υι

Collect input lines until an empty line is reached.

⪫υ¶¦

Join the lines on newline characters.

⪪..."

Split the input on quotes.

⭆...

Map over each part and concatenate the results for implicit print.

⎇κ...ι

Leave the first part unchanged.

⁺ײ§'`κι

Prefix the appropriate quote, doubled.

\$\endgroup\$
  • \$\begingroup\$ I was waiting for a Charcoal solution. Nice! \$\endgroup\$ – HighlyRadioactive Aug 24 at 11:24
2
\$\begingroup\$

R, 40 bytes

cat(scan(,"",,,'"',""),sep=c("``","''"))

Try it online!

Reads string input, separating at each ", giving a vector of strings. Then pastes those strings, alternating between the double backticks and the double apostrophes as separators, recycling them as needed.

Someone will probably post a shorter R answer based on a regex... Still, this answer is more typical of R, I think.

Explanation of the scan(,"",,,'"',"") part:

scan(, # empty first parameter: read from STDIN
  "",  # type of input is a string
  ,    # default 3rd parameter nmax
  ,    # default 4th parameter n
  '"', # separate on character "
  "")  # do not treat any characters as quotations marks (necessary to handle ' in the input)
\$\endgroup\$
2
\$\begingroup\$

Perl 6, 23 bytes

{S:g/\"(.*?)\"/``$0''/}

Try it online!

Darn, the obvious solution is shorter. Replaces each quoted portion with a version with the appropriate quotes.

Perl 6, 24 bytes

{S:g{\"}=<`` ''>[$++%2]}

Try it online!

Replaces each double quote, alternating between the two sets of characters.

\$\endgroup\$
1
\$\begingroup\$

Retina, 15 bytes

"
""
Y`"`\`\`''

Try it online! Edges out the boring Retina 0.8.2 answer by 1 byte. Explanation:

"
""

Duplicate all of the quotes.

Y`"`\`\`''

Cyclically replace the quotes with pairs of backticks and single quotes.

Boring 16-byte Retina 0.8.2 answer for completeness:

s`"(.*?)"
``$1''

Try it online!

\$\endgroup\$
1
\$\begingroup\$

PHP, 62 bytes

Non-RegEx solution:

for(;''<$l=$argv[1][$i++];)echo$l=='"'?["''","``"][++$j%2]:$l;

Try it online!


PHP, 48 bytes

Port of Arnauld's RegEx solution:

<?=preg_replace('/"(.*?)"/s',"``$1''",$argv[1]);

Try it online!

\$\endgroup\$
1
\$\begingroup\$

C (gcc), 69 68 bytes

t=39,z;f(char*s){z=*s-34?*s:257*(t^=71);printf("%s",&z);*++s&&f(s);}

Try it online!

One byte shaved off by @ceilingcat!

\$\endgroup\$
1
\$\begingroup\$

Labyrinth, (43?) 53 bytes

396"
 } "",)@
  ~"  (
 "~ 3_:
""" 4
" .;-
=   ;
..::;

Try it online!

A golfed version of this, much simpler, 92 byte program:

3 """
9 " ",)@
}96 " (
    " :_34-;;
    "     ; :
   """"""". :
   "        .
   """"""""=.

If we don't need to handle input containing the zero byte then 43 bytes:

39}9
@  6
`,""
`  "
: ."=..
_ ;   "
34-;;::
\$\endgroup\$
1
\$\begingroup\$

Python 2, 57 bytes

lambda s:re.sub('"(.*?)"',r"``\1''",s,flags=16)
import re

Try it online!

Although I really like Jitse's answer.

\$\endgroup\$
  • \$\begingroup\$ -4 Bytes if you use inline flags instead of the flags argument: r'(?s)"(.*?)"' \$\endgroup\$ – Triggernometry Aug 27 at 14:27
1
\$\begingroup\$

(GNU) sed, 38 33 30 bytes

-4 by removing the -n flag and implicitly printing on n, -1 by reusing previous /expression/, thanks @Cowsquack. -3 by using implicit branch-to-end.

:a
s/"/``/;T
:b
s//''/;ta
n;bb

Try it online! Try it online! Try it online!

Some pretty basic label jumping. This can probably be golfed by a byte or two.

:a          # label a
s/"/``/;T   # replace " -> ``. If unsuccessful, move to next line
:b          # label b
s//''/;ta   # replace " (implicit) -> ''. If successful, jump to a (w/o reading new line)
n;bb        # read in the next line, but jump to label b. 
\$\endgroup\$
  • 1
    \$\begingroup\$ Btw typically the flags used are specified in the header. You can golf a byte using codegolf.stackexchange.com/a/167295/41805, in addition some of the branching logic can be removed. Then making the solution work without the -n flag should save a bit more. (And of course there is the trivial sed -z solution which I presume you to have intentionally avoided) \$\endgroup\$ – Kritixi Lithos Aug 25 at 13:56
  • \$\begingroup\$ Alright, I dug back into man sed for a bit and got to 30. Feel free to let me know anything I missed, you've got the golf experience on this lang. (Oh, -z is new to me, but I agree. I'll stay without it.) \$\endgroup\$ – GammaFunction Aug 25 at 14:17
  • \$\begingroup\$ Nicely done, I am always glad to see a sed answer \$\endgroup\$ – Kritixi Lithos Aug 25 at 14:59
1
\$\begingroup\$

05AB1E, 15 bytes

'"¡ā¨„'`sè2×.ιJ

Try it online!

No regexes in 05AB1E, so we split on ", make a list of alternating `` and '', then interleave the two.

\$\endgroup\$
  • 1
    \$\begingroup\$ Ok, looks like I don't have to fix and undelete my answer. ;) \$\endgroup\$ – Kevin Cruijssen Aug 26 at 11:57
1
\$\begingroup\$

Haskell, 67 60 58 bytes

(#0)
('"':x)#n=["``","''"]!!n++x#(1-n)
(a:b)#n=a:b#n
x#n=x

Try it online!

The relevant function is (#0).

Since I originally thought the question also required us to convert single quotes here is a version that handles both:

Haskell, 125 bytes

(#(1<0,1<0))
('"':x)#(m,n)=last("``":["\""|m])++x#(not m,n)
('\'':x)#(m,n)=last('`':['\''|n]):x#(m,not n)
(a:x)#n=a:x#n
x#n=x

Try it online!

\$\endgroup\$
  • \$\begingroup\$ "\"" should be "''" (two apostrophes) \$\endgroup\$ – siracusa Aug 26 at 3:23
  • \$\begingroup\$ @siracusa Thanks, I assumed since you can use " in tex you could use it here. \$\endgroup\$ – Wheat Wizard Aug 26 at 14:31
1
\$\begingroup\$

QuadR, 14 bytes

"(.*?)"
``\1''

Try it online!

Simple find/replace using @Adám's wrapper for Dyalog APL's ⎕Replace function.

How:

"(.*?)" ⍝ PCRE, finding anything between two double quotes and assigning it to group 1
``\1''  ⍝ Transformation string, replacing the match with ``group_1''.
\$\endgroup\$
0
\$\begingroup\$

Red, 79 bytes

func[s][q:"^""parse s[any[to change[q copy t to q q](rejoin["``"t"''"])skip]]s]

Try it online!

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

Jelly, 13 bytes

ṣ”"µJḊ⁾`'ṁḤż@

A full program.

Try it online!

How?

ṣ”"µJḊ⁾`'ṁḤż@ - Main Link: list of characters, T   e.g. ..."hi" - she "said"...
 ”"           - character '"'                           '"'
ṣ             - split (T) at ('"')                      ["...","hi"," - she ","said","..."]
   µ          - (call that X) start a new monadic chain
    J         - range of length (of X)                  [1,2,3,4,5]
     Ḋ        - dequeue                                 [2,3,4,5]
      ⁾`'     - list of characters                      ["`","'"]
         ṁ    - mould like                              ["`","'","`","'"]
          Ḥ   - double                                  ["``","''","``","''"]
           ż@ - (with reversed @rguments) zip (with X)  [["...","``"],["hi","''"],[" - she ","``"],["said","''"],["..."]]
              - implicit (smashing) print               ...``hi'' - she ``said''...
\$\endgroup\$
0
\$\begingroup\$

Lua, 36 bytes

print((...):gsub('"(.-)"',"``%1''"))

Try it online!

Wow, only two chars longer than js solution.

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

Perl 5 -p0, 19 bytes

s/"(.*?)"/``$1''/gs

Try it online!

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

Stax, 11 bytes

û╩↕H£ñ╟Uzay

Run and debug it

Procedure:

  1. Take all input, newlines and all.
  2. Regex replace '"' with a block that produces alternating outputs of pairs of backticks and foreticks(?)
\$\endgroup\$
0
\$\begingroup\$

Java 8, 40 bytes

s->s.replaceAll("\"([^\"]+)\"","``$1''")

Try it online.

Explanation:

s->                             // Method with String as both parameter and return-type
  s.replaceAll("\"([^\"]+)\"",  //  Replace all these matches,
               "``$1''")        //  with this replacement 

Regex explanation:

 "([^"]+)"                      // MATCH:
 "                             "//  A literal "
   [^"]+                       "//  Followed by 1 or more non-" characters
  (     )                       //  (captured in capture group 1)
         "                     "//  Followed by a literal " again

``$1''                          // REPLACEMENT:
``                              //  Literal ``
  $1                            //  Followed by the match of capture group 1
    ''                          //  Followed by a literal ''
\$\endgroup\$

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.