6 golfed 28 bytes :)

# JavaScript (ES6), 380352352 324 bytes

(Note: Code uses caret notation, as it contains some unprintable characters. To get original code, click herehere and select the raw data. And no, h is not a CJam program. ;)

d=s=>{a=' ',u=n=>(n|0)%2u=n=>r>>n&1?'!':a,v=n=>(n|0)%2v=n=>r>>n&1?'_':a,g='ABCDEFGHIJLNOPQRSTUYZabcdefghijlnopqrstuyz0123456789-? ÿ',h='{vUnWSuz(lTb}[;B7V|>O{vFnWSur lTbf[;B7Vd>O}(O/:7w)^??^BK\0^G'^BK^0^G',x=y=z='';for(i=0;i<s.length;x+=a+v(r0)+a,y+=u(r/164)+v(r/21)+u(r/83),z+=u(r/646)+v(r/42)+u(r/325)){q=g.indexOf(s.charAt(i++)s[i++]);if(q<0)return d('ÿ');r=hdÿ;r=h.charCodeAt(q)}return x+
+y+${y} +z}  Called as d("7-seg display") or similar. Works in Firefox 3940, but may not in other browsers. For some reason, the HTML/JS snippet does not save the non-printables, so to test, but you can copy-paste the raw data from over here and paste it hereover here. Edit 1: Saved a bunch of space by creating mini-functions to determine whether !, _, or is needed. Edit 2: Saved a bunch more space using the tricks I've learned since I last visited this post. # JavaScript (ES6), 380352 bytes (Note: Code uses caret notation, as it contains some unprintable characters. To get original code, click here and select the raw data. And no, h is not a CJam program. ;) d=s=>{a=' ',u=n=>(n|0)%2?'!':a,v=n=>(n|0)%2?'_':a,g='ABCDEFGHIJLNOPQRSTUYZabcdefghijlnopqrstuyz0123456789-? ÿ',h='{vUnWSuz(lTb}[;B7V|>O{vFnWSur lTbf[;B7Vd>O}(O/:7w)^??^BK\0^G',x=y=z='';for(i=0;i<s.length;x+=a+v(r)+a,y+=u(r/16)+v(r/2)+u(r/8),z+=u(r/64)+v(r/4)+u(r/32)){q=g.indexOf(s.charAt(i++));if(q<0)return d('ÿ');r=h.charCodeAt(q)}return x+ +y+ +z}  Called as d("7-seg display") or similar. Works in Firefox 39, but may not in other browsers. For some reason, the HTML/JS snippet does not save the non-printables, so to test, copy-paste the raw data from over here and paste it here. Edit 1: Saved a bunch of space by creating mini-functions to determine whether !, _, or is needed. # JavaScript (ES6), 380352 324 bytes (Note: Code uses caret notation, as it contains some unprintable characters. To get original code, click here and select the raw data. And no, h is not a CJam program. ;) d=s=>{a=' ',u=n=>r>>n&1?'!':a,v=n=>r>>n&1?'_':a,g='ABCDEFGHIJLNOPQRSTUYZabcdefghijlnopqrstuyz0123456789-? ÿ',h='{vUnWSuz(lTb}[;B7V|>O{vFnWSur lTbf[;B7Vd>O}(O/:7w)^??^BK^0^G',x=y=z='';for(i=0;i<s.length;x+=a+v(0)+a,y+=u(4)+v(1)+u(3),z+=u(6)+v(2)+u(5)){q=g.indexOf(s[i++]);if(q<0)return dÿ;r=h.charCodeAt(q)}return x+${y}
+z}


Called as d("7-seg display") or similar. Works in Firefox 40, but may not in other browsers. For some reason, the HTML/JS snippet does not save the non-printables, but you can copy-paste the raw data from over here.

Edit 1: Saved a bunch of space by creating mini-functions to determine whether !, _, or is needed.

Edit 2: Saved a bunch more space using the tricks I've learned since I last visited this post.

5 Fixed display error
d=s=>{a=' ',u=n=>(n|0)%2?'!':a,v=n=>(n|0)%2?'_':a,g='ABCDEFGHIJLNOPQRSTUYZabcdefghijlnopqrstuyz0123456789-? ÿ',h='{vUnWSuz(lTb}[;B7V|>O{vFnWSur lTbf[;B7Vd>O}(O/:7w)^??^BK\0^G',x=y=z='';for(i=0;i<s.length;x+=a+v(r)+a,y+=u(r/16)+v(r/2)+u(r/8),z+=u(r/64)+v(r/4)+u(r/32)){q=g.indexOf(s.charAt(i++));if(q<0)return d('ÿ');r=h.charCodeAt(q)}return x+
+y+
+z}


+y+ +z}

d=s=>{a=' ',u=n=>(n|0)%2?'!':a,v=n=>(n|0)%2?'_':a,g='ABCDEFGHIJLNOPQRSTUYZabcdefghijlnopqrstuyz0123456789-? ÿ',h='{vUnWSuz(lTb}[;B7V|>O{vFnWSur lTbf[;B7Vd>O}(O/:7w)^??^BK\0^G',x=y=z='';for(i=0;i<s.length;x+=a+v(r)+a,y+=u(r/16)+v(r/2)+u(r/8),z+=u(r/64)+v(r/4)+u(r/32)){q=g.indexOf(s.charAt(i++));if(q<0)return d('ÿ');r=h.charCodeAt(q)}return x+


+y+ +z}

d=s=>{a=' ',u=n=>(n|0)%2?'!':a,v=n=>(n|0)%2?'_':a,g='ABCDEFGHIJLNOPQRSTUYZabcdefghijlnopqrstuyz0123456789-? ÿ',h='{vUnWSuz(lTb}[;B7V|>O{vFnWSur lTbf[;B7Vd>O}(O/:7w)^??^BK\0^G',x=y=z='';for(i=0;i<s.length;x+=a+v(r)+a,y+=u(r/16)+v(r/2)+u(r/8),z+=u(r/64)+v(r/4)+u(r/32)){q=g.indexOf(s.charAt(i++));if(q<0)return d('ÿ');r=h.charCodeAt(q)}return x+
+y+
+z}

4 Golfed code and tidied post

# JavaScript (ES6), 380380 352 bytes

d=s=>{t=n=>a=' ',u=n=>(n|0)%2?'!':a,v=n=>(n|0)%2?'_':a,g='ABCDEFGHIJLNOPQRSTUYZabcdefghijlnopqrstuyz0123456789-? ÿ',h='{vUnWSuz(lTb}[;B7V|>O{vFnWSur lTbf[;B7Vd>O}(O/:7w)^??^BK\0^G',a=' ',b='!',c='_',x=y=z='';for(i=0;i<s.length;x+=a+length;x+=a+v(r%2?c:ar)+a,y+=(ty+=u(r/16)?b:a)+(t+v(r/2)?c:a)+(t+u(r/8)?b:a),z+=(tz+=u(r/64)?b:a)+(t+v(r/4)?c:a)+(t+u(r/32)?b:a)){q=g.indexOf(s.charAt(i++));if(q<0)return d('ÿ');r=h.charCodeAt(q)}return x+
+y+
+z}


+y+ +z}

Called as d("7-seg display") or similar. Works in Firefox 39, but may not in other browsers. For easy testingsome reason, the HTML/JS snippet does not save the non-printables, so to test, copy-paste the raw data from over here and paste it here.

ThenAs an example, here's the encoded version of A:

     1
---
16 |   | 8
2 ---
64 |   | 32

Dec: 64 + 32 + 16 + 8 + 2 + 1 = 123
Hex: 40 + 20 + 10 + 8 + 2 + 1 = 7B = u+007B = {


I decipheredthen stuffed the Unicode values corresponding toencoded version of each 7-seg character, and stuffed them all in h. However, 8 resulted in 007f (the delete control code; constant no matter how the segments are arranged), space resulted in 0000 (the nullnull code; also constant), - resulted in 0002, and error resulted in 0007. I copy-pasted the raw bytes into the correct position for 8, -, and error; space was easily achieved with \0.

After all this encoding, all I had to do was use it to decode the string and output it in a 7-seg readable format. I used a for loop and three variables (x, y, and z, each corresponding to an output line) to go through each character in the string and add its 7-seg equivalent to the output. I chose ÿ for the error character because AFAIK, it's not on any keyboard, and it's the last character in the u+0000-u+00ff range. Perhaps I could have been witty and chosen Ξ (Greek letter xi) instead.... ;)

Edit 1: Saved a bunch of space by creating mini-functions to determine whether !, _, or is needed.

# JavaScript (ES6), 380 bytes

d=s=>{t=n=>(n|0)%2,g='ABCDEFGHIJLNOPQRSTUYZabcdefghijlnopqrstuyz0123456789-? ÿ',h='{vUnWSuz(lTb}[;B7V|>O{vFnWSur lTbf[;B7Vd>O}(O/:7w)^??^BK\0^G',a=' ',b='!',c='_',x=y=z='';for(i=0;i<s.length;x+=a+(r%2?c:a)+a,y+=(t(r/16)?b:a)+(t(r/2)?c:a)+(t(r/8)?b:a),z+=(t(r/64)?b:a)+(t(r/4)?c:a)+(t(r/32)?b:a)){q=g.indexOf(s.charAt(i++));if(q<0)return d('ÿ');r=h.charCodeAt(q)}return x+
+y+
+z}


Called as d("7-seg display") or similar. Works in Firefox 39, but may not in other browsers. For easy testing, copy-paste the raw data from over here and paste it here.

Then I deciphered the Unicode values corresponding to each 7-seg character, and stuffed them all in h. However, 8 resulted in 007f (the delete control code; constant no matter how the segments are arranged), space resulted in 0000 (the null code; also constant), - resulted in 0002, and error resulted in 0007. I copy-pasted the raw bytes into the correct position for 8, -, and error; space was easily achieved with \0.

After all this encoding, all I had to do was use it to decode the string and output it in a 7-seg readable format. I used a for loop and three variables (x, y, and z, each corresponding to an output line) to go through each character in the string and add its 7-seg equivalent to the output. I chose ÿ for the error character because AFAIK, it's not on any keyboard, and it's the last character in the u+0000-u+00ff range. Perhaps I could have been witty and chosen Ξ (Greek letter xi) instead.... ;)

# JavaScript (ES6), 380 352 bytes

d=s=>{a=' ',u=n=>(n|0)%2?'!':a,v=n=>(n|0)%2?'_':a,g='ABCDEFGHIJLNOPQRSTUYZabcdefghijlnopqrstuyz0123456789-? ÿ',h='{vUnWSuz(lTb}[;B7V|>O{vFnWSur lTbf[;B7Vd>O}(O/:7w)^??^BK\0^G',x=y=z='';for(i=0;i<s.length;x+=a+v(r)+a,y+=u(r/16)+v(r/2)+u(r/8),z+=u(r/64)+v(r/4)+u(r/32)){q=g.indexOf(s.charAt(i++));if(q<0)return d('ÿ');r=h.charCodeAt(q)}return x+


+y+ +z}

Called as d("7-seg display") or similar. Works in Firefox 39, but may not in other browsers. For some reason, the HTML/JS snippet does not save the non-printables, so to test, copy-paste the raw data from over here and paste it here.

As an example, here's the encoded version of A:

     1
---
16 |   | 8
2 ---
64 |   | 32

Dec: 64 + 32 + 16 + 8 + 2 + 1 = 123
Hex: 40 + 20 + 10 + 8 + 2 + 1 = 7B = u+007B = {


I then stuffed the encoded version of each 7-seg character in h. However, 8 resulted in 007f (the delete control code; constant no matter how the segments are arranged), space resulted in 0000 (the null code; also constant), - resulted in 0002, and error resulted in 0007. I copy-pasted the raw bytes into the correct position for 8, -, and error; space was easily achieved with \0.

After all this encoding, all I had to do was use it to decode the string and output it in a 7-seg readable format. I used a for loop and three variables (x, y, and z, each corresponding to an output line) to go through each character in the string and add its 7-seg equivalent to the output. I chose ÿ for the error character because AFAIK, it's not on any keyboard, and it's the last character in the u+0000-u+00ff range. Perhaps I could have been witty and chosen Ξ (Greek letter xi) instead.... ;)

Edit 1: Saved a bunch of space by creating mini-functions to determine whether !, _, or is needed.

3 Removed non-working snippet
2 Tidied explanation
1