Convert a Forsyth-Edwards Notation string to ASCII art

Retina, 13 bytes

\d
$* 
/
¶

|

Try it online!

Explanation

The first part (note the trailing space):

\d
$* 

is to convert a to the specific number of spaces. Retina has a $* feature to repeat. The way it works is: <num>$*<char> if there is no <num>, Retina will assume $& or the matched string, in this case the matched number.

The next part:

/
¶

is pretty simple, it replaces all / with which is a newline.

The last part works the same:

    
|

This will replace everything (hence why there is nothing on the first line) with |. Putting a | everywhere.


Ruby - 75 82 78 76 75 62 59 58 57 56 bytes

->n{"|#{n.gsub(/\d|
/){' '*$&.hex}.chars*?|}|".tr'/',$/}

Saved a few bytes thanks to Ventero

Let me explain (with \n replacing the literal newline):

->n{"...".tr'/',$/}

This implicitly returns the value of the string, with each / replaced with a newline (by default, $/ contains a newline)

"|#{...}|"

This is super simple; it's just a string containing a pipe, string interpolation, and another pipe. The string interpolation is evaluated

n.gsub(/\d|\n/){' '*$&.hex}...

This replaces every number with that many spaces. I can save a few bytes by also finding newlines here; because hex returns 0 if the string isn't a valid number, when it finds a newline –- i.e. the one at the end of the result of gets –- it replaces it with a 0-length string, effectively deleting it. Without this, there would be a trailing pipe.

$& is a magic variable which represents the complete text of the latest variable match, which lets me save a byte by eliminating |d|. I can save another byte by using .hex instead of .to_i, which works because every number is less than 9, which means that hex and decimal have the same values.

.chars*?|

This puts a pipe between every character. Note that this is what puts the pipes on either side of the lines (except the first and last) because the slashes, which eventually turn into newlines through tr, count as characters, and are therefore surrounded by pipes. The ?| just means "the one-character string "|"".

And... that's it. It's a frankly scandalously simple program. It just uses a lot of sneaky syntax tricks.


Perl, 28 bytes

Includes +2 for -lp

Give input on STDIN

fen.pl <<< "r1bk3r/p2pBpNp/n4n2/1p1NP2P/6P1/3P4/P1P1K3/q5b1"

fen.pl:

#!/usr/bin/perl -lp
s/\d/$"x$&/eg;s/|/|/g;y;/;

Actually in the league of some golfing languages...

Notice that the file based version needs the final newline in the file so that one is really 29 bytes. But the commandline version doesn't need that extra newline and therefore the code counts as 28 bytes:

perl -lpe 's/\d/$"x$&/eg;s/|/|/g;y;/;' <<< "r1bk3r/p2pBpNp/n4n2/1p1NP2P/6P1/3P4/P1P1K3/q5b1"