Skip to main content
5 of 5
deleted 106 characters in body
Martin Ender
  • 197.2k
  • 67
  • 447
  • 975

Retina, 159 bytes

Byte count assumes ISO 8859-1 encoding. The leading linefeed is significant.


99$*1 bottles of beer
1
1$'W, 1$'.¶Take one down and pass it around, $'W.¶¶
1+
$.&
G-3`
W
 on the wall
T`s``\b1 .+
.+ \B
Go to the store and buy some more, 99

Try it online!

I can't be believe I (or anyone else) have ever done this in Retina...

Explanation


99$* bottles of beer

We start by replacing the empty input with 99 1s followed by bottles of beer.

1
1$'W, 1$'.¶Take one down and pass it around, $'W.¶¶

Now we replace each of those 1s with the substitution pattern on the second line. Here $' stands for the string after each match, and we use W as a placeholder for later. Note that the occurrences of $' on the first line are "incremented" by prepending a 1. We've got most of the work done already, except that the numbers are in unary instead of decimal, and we've got Ws instead of on the walls and the last verse is off.

1+
$.&

This does the unary-to-decimal conversion by matching each run of 1s and replacing it with its length.

G-3`

This is a "grep" stage. The regex is empty, so it always matches, but the -3 limit means that only lines up to the third from the end are kept, so the last two are discarded. This gets rid of the two extraneous linefeeds at the end.

W
 on the wall

Now we substitute our W placeholder. At this point, we've got everything in place except that the last verse is still wrong.

T`s``\b1 .+

This fixes the pluralisation by removing all ss from the match of the regex at the end, which matches anything after a 1 (on the same line).

Note that the last line doesn't have 0 since the unary representation of it is an empty string it wasn't matched by the conversion stage. Instead there will be two spaces in a row.

.+ \B
Go to the store and buy some more, 99

This is the only case where there is no word boundary after a space, so we detect the line like this and replace it with the correct lyrics.

Martin Ender
  • 197.2k
  • 67
  • 447
  • 975