[Question]
  [
Given any of the following characters (or a newline):
```
`1234567890-=~!@#$%^&*()_+qwertyuiop[]\QWERTYUIOP{}|asdfghjkl;'ASDFGHJKL:"zxcvbnm,./ZXCVBNM<>?
```
Your program must output the row that it is on the keyboard
---
Because my keyboard is (almost) out of battery, your code must be as short as possible
---
The keyboard your program should use (for the row lookup), should look like:
``Row 1:``~`` `!1``@2` `#3``$4` `%5``^6` `&7``\*8` `(9``)0` `\_-``+=`   
  
`Row 2:` `Q` `W` `E` `R` `T` `Y` `U` `I` `O` `P` `{[` `}]` `|\`  
`Row 3:` `A` `S` `D` `F` `G` `H` `J` `K` `L` `:;` `"'` `↵ return`  
`Row 4:` `Z` `X` `C` `V` `B` `N` `M` `<,` `>.` `?/`   
`Row 5:`   `space``
Where `↵  return` is a newline. Empty keys don't mean anything.
## Examples
```
"$"
1
"R"
2
"a"
3
"?"
4
"\n"
3
" "
5
```
where `\n` is a newline character.
## Specifications
* Your program should be case insensitive
* Your program only needs to handle the characters on the keyboard shown
  
[Answer]
# JavaScript (ES6), ~~105~~ ~~102~~ 101 bytes
```
c=>/[~`0-9!@#-&^(-+_=-]/.test(c)+/[asdfghjkl;:'"\n]/i.test(c)*3+/[zxcvbnm,<.>/?]/i.test(c)*4||++c*7^2
```
## Explanation
In JavaScript `test` returns a boolean which acts the same as `1` or `0` so I multiply them by their row. Testing for row 2 took the most bytes so I used that one as the default if no others matched.
```
c=>
  /[~`0-9!@#-&^(-+_=-]/.test(c)   // row 1 regex
  +/[asdfghjkl;:'"\n]/i.test(c)*3 // row 3 regex
  +/[zxcvbnm,<.>/?]/i.test(c)*4   // row 4 regex
  ||++c                           // space ++ = 1, any character on row 2 ++ = NaN
    *7^2                          // 7 XOR 2 = 5, NaN XOR 2 = 2
```
## Test
```
var solution = c=>/[~`0-9!@#-&^(-+_=-]/.test(c)+/[asdfghjkl;:'"\n]/i.test(c)*3+/[zxcvbnm,<.>/?]/i.test(c)*4||++c*7^2
```
```
<textarea id="input">-</textarea><br />
<button onclick="result.textContent=solution(input.value)">Go</button>
<pre id="result"></pre>
```
[Answer]
# Pyth, ~~62~~ ~~66~~ 65 bytes
```
?zh@+,4Zmid2c.Bi."0fÀÓ¸[9Ñ¶¤KïLäHÉðbÀ`]ü©¬vS"16 2-CzCd3
```
[Try it online.](http://pyth.herokuapp.com/?code=%3Fzh%40%2B%2C4Zmid2c.Bi.%220f%1E%C3%80%C3%93%C2%B8%5B%C2%809%C3%91%C2%B6%C2%A4K%0B%C3%AFL%C3%A4H%C3%89%C2%95%C3%B0b%C3%80%60%C2%8A%5D%C2%94%05%01%C3%BC%C2%87%C2%A9%1A%C2%ACvS%2216%202-CzCd3&test_suite=1&test_suite_input=%60%0Aq%0Aa%0Az%0A%20&debug=0)
Uses a packed string representing a number in hex which, when chopped into two-bit chunks, represents the row of every character except  and `!` as a value from 0 to 3. We leave out  and `!` so we don't have to store 4 or have a 0 at the start of this number, then add their row values using `+,4Z`. Once we've turned the string into row values, all we have to do is use the character code of the input to index into the array of values, and then add 1.
Newline is handled separately because it's interpreted by Pyth as an empty string and so has a character code of 0.
This would be shorter if I could figure out how to use base 256 in Pyth, but I can't quite make it work.
[Answer]
## [Glava 1.5](https://github.com/GamrCorps/Glava), 164 bytes
Glava is a dialect of Java that makes Java code shorter. This code is unfortunately non-competitive as the commit (2 hours late...) used was made after this challenge, which fixed some vital bugs that would not allow this program to work.
```
p(A[0].matches("[`0-9-=~!@#$%^&*()_+]")?1:A[0].replace("\\n","\n").matches("(?i)[asdfghjkl;':\"\n]")?3:A[0].matches("(?i)[zxcvbnm,.\\/<>?]")?4:A[0].matches(" ")?5:2
```
This is a full program that takes input via command-line arguments. Works by simply testing for which row regex it matches, then outputs the corresponding number.
[Answer]
# Python 3, 142
```
print(int(("~`!1@2#3$4%5^6&7*8(9)0_-+=""qwertyuiop{[}\|"+"]"*11+'asdfghjkl;:"\n'"'"*13+"zxcvbnm,<.>/""?"*14+" ").index(input().lower())/26)+1)
```
There is probably a shorter way that I am overlooking ¯\\_(ツ)\_/¯
[Answer]
# [Pyth](https://pyth.herokuapp.com/), 98
```
|+++l:"~`0123456789!@#$%^&*()_-=+"z1*l:"asdfghjkl;:'\"\n"rz0 1 3*l:"zxcvbnm,<.>/? "rz0 1 4 l:dz1 2
```
not sure how to get the 0-9 range working for some reason :|, inspired by user81655's answer
[Answer]
# Bash, 108
No Bash answer?
Bash answer. `grep -Fin` is definitely the right tool for this job.
This program is in two files.
## `k`, 73 bytes
```
`1234567890-=~!@#$%^&*()_+
qwertyuiop[]\{}|
asdfghjkl;':"
zxcvbnm,./<>?
```
There are 5 lines, the last one is a space. If you have trouble reproducing the file, the base64 is:
```
YDEyMzQ1Njc4OTAtPX4hQCMkJV4mKigpXysKcXdlcnR5dWlvcFtdXHt9fAphc2RmZ2hqa2w7JzoiCnp4Y3Zibm0sLi88Pj8KIA==
```
## `b`, 34 bytes
This is the program itself, it takes input as the only command line argument.
```
grep -Fin "$1" k|tail -n3|head -c1
```
Score: 34 + 73 + 1 (for `k`'s filename) = 108 bytes
## Ungolfed
```
grep --fixed-strings --ignore-case --line-number "$1" k|tail --lines=3|head --bytes=1
```
## Explanation
* `grep` - search a file for lines matching a string or regular expression, output only those lines
* `-F` aka `--fixed-strings` - disable regular expressions so `[` etc. are handled correctly
* `-i` aka `-y` aka `--ignore-case` - case-insensitive matching
* `-n` aka `--line-number` - show the line number and : before every line (e.g. `4:zxcvbnm,./<>?`)
* `"$1"` - search for the script's first command-line argument, the quotes are necessary to handle newline and space
* `k` - search in file `k`
* This `grep` command will match all five lines if the input is a newline, and only one line otherwise.
* `|` - pipe, send standard output of one command to standard input of the next
* `tail` - output the last N lines or characters of standard input
* `-n3` aka `--lines=3` - output the last 3 lines
* If the input wasn't a newline, there is only one line to process, which starts with the row number because of the `-n` flag on `grep`. Otherwise, this command takes only lines 3, 4 and 5 (the last 3 lines).
* `|` - pipe
* `head` - output the first N lines or characters of standard input
* `-c1` aka `--bytes=1` - output the first character
* If the input wasn't a newline, this takes the first character, which is the line number where the input is found. If the input is a newline, it takes the first character of lines 3, 4 and 5 combined, which is 3, which happens to be the correct row number for newline.
[Answer]
## Japt, ~~73~~ ~~70~~ 66 bytes
```
2+`qØÆyuiop\{}[]|\\1dfghjkl;:
'1zxcvbnm,.<>?/\"1 `q1 ®bUv)<0} b!1
```
[Try it online!](http://ethproductions.github.io/japt?v=master&code=MitgcdjGeXVpb3Bce31bXXxcXDFkZmdoamtsOzoKJzF6eGN2Ym5tLC48Pj8vXCIxIGBxMSCuYlV2KTwwfSBiITE=&input=Igoi) (in the example, the input is literally a newline)
[Answer]
# Java, 300 bytes
```
import java.util.Scanner;public class A{public static void main(String[] args){String g="~`!1@2#3$4%5^6&7*8(9)0_-+=qQwWeErRtTyYuUiIoOpP[{]}\\|aAsSdDfFgGhHjJkKlL;:\'\"\r";Scanner i=new Scanner(System.in);int f=g.indexOf((i.nextLine().charAt(0)));System.out.print(f<0?4:(f<26?1:(f<53?2:(f<76?3:5))));}}
```
I'm not an expert, and this is my first attempt at golfing, but I figured, what the hell, why not? Above is the full program version, the actual code that goes into it would most likely take a decent amount of characters off.
[Answer]
## Pyth, 105 bytes
```
J?<l-c".^$*+?{}[]\|()"1]z14+\\zrz0?qJd5?:"qwertyuiop[]\|"J)2?:"asdfghjkl;':\"\n"J)3?:"zxcvbnm,./<>?"J)4 1
```
Explanation:
```
J?<l-c".^$*+?{}[]\|()"1]z14+\\zrz0     # Escape input if regex metachar
?qJd5                                  # Check space
?:"qwertyuiop[]\|"J)2                  # Check second row
?:"asdfghjkl;':\"\n"J)3                # Check third row
?:"zxcvbnm,./<>?"J)4                   # Check fourth row
1                                      # If none of these, must be on first row.
```
I decided to choose the first row as the "must be if nothing else" row because it required the most bytes to represent even after golfing.
[Answer]
# Perl 6, 128 bytes
```
say 1+(/<[-\d=~!@#$%^&*()_+/`]>/,/<[qwertyuiop[\]\\{}|]>/,/<[asdfghjkl;':"\n]>/,/<[zxcvbnm,./<>?]>/,' ').first: @*ARGS.lc~~*,:k
```
I make a list of regexes containing character classes along with a string literal space. I then call the `first` method on the list (which is just the method version of the `first` higher order function), using smartmatch to compare the argument passed to the program against the current item in the list. Note that smartmatch does "the right thing" for both regexes and a string literal. The `:k` optional parameter to `first` causes the method to return the index of the matching item in the list, which I then add 1 to and output via `say`.
Note that when using this program you will have to properly escape certain characters like ` and space in your shell. For instance: perl6 keyboard.p6 \`
[Answer]
## Python 3, 89 bytes
```
print("qwertyuiop{}[]\\|asdfghjkl;:\"\n'''zxcvbnm,.<>/???? ".find(input().lower())//16+2)
```
As I can't comment yet, I'm posting the improvement for the [current Python 3 answer](https://codegolf.stackexchange.com/a/68746/76276) separately.
**Edit**: All code in `print` now and further tweaked.
[Answer]
## JavaScript ES6, 114 bytes
```
n=>[`qwertyuiop{}[]|\\`,`asdfghjkl;:
'`,`zxcvbnm,.<>?/"`,` `].map(x=>+(x.indexOf(n.toLowerCase())<0)).indexOf(0)+2
```
Another JavaScript solution. The principle is to return the index of the input char in the array of rows plus 2 (so as the 0-9 row returns -1, i.e. not exists, -1+2=1. `q` is in the first string of the array, so it returns 0+2=2nd row).
[Answer]
# Perl, ~~96~~ ~~77~~ 76 bytes
Run using `perl -p`. Make sure you're feeding it just single characters; for example, to run it from a file `key.pl` (to avoid mucking around with shell escape sequences) `echo -n q|perl -p key.pl`.
```
$_=/[\d~`!@#-&(-+_=-]/+/[adfghjkls"':;
]/i*3+/[bcnmvxz<>,.?\/]/i*4+/ /*5||2
```
Abusing the regex range functionality is fun.
[Answer]
# PHP, 173 bytes
The idea here was to use the regex capturing group number as the row index. Probably some more optimizations in the regex itself. 
```
$i=$argv[1];preg_match("%([!#-&\(-+-0-9=@^-`~])|([EIO-RT-UWY[-]eio-rt-uwy{-}])|([\"':-;ADF-HJ-LSadf-hj-ls])|([,.-/<>-?B-CM-NVXZb-cm-nvxz])%",$i,$m);echo array_flip($m)[$i];
```
The `preg_match()` call will create an array `$m` of matches, and if we were to print that, it'd look something like this (assuming `z` was the input):
```
Array ( [0] => 'z', [1] => '', [2] => '', [3] => '', [4] => 'z' )
```
Flipping that array, by swapping keys and values, moves left to right and only keeps the last distinct key, so we end up with:
```
Array ( 'z' => 4, '' => 3 )
```
Then we use the input character as the index in the array to get our result.
[Try it out here](https://3v4l.org/jeris).
[Answer]
# C, ~~145 143 136 132 127 106~~ 104 bytes
```
#define c"\x7ea6a6f8\x5777595"
f(a){return a-32?L"\x200000\0\xf3008020\xf2a00000"c c[a>>4]>>a%16*2&3:4;}
```
[Try it online!](https://tio.run/##bcrRCoIwGIbhc69iLMwtEtamzhLWDXQHLehnbuJBo8RAEq99paf5Hb08fCZtjAlhU1vXeosM1oO0UEDhSj3kUsr8mOPIEaBjZ/t35xGkgp8vvx9n8zTTgxOMlYzPxWFRbJC5glLZTSmID8WOb8Upq6bwgNYTOkbPrvW9Iziutcd7R5J7Qmn1z691hnX@rDNaeApf "C (gcc) – Try It Online")
~~This uses `index()` from POSIX.1-2001 and is deprecated in POSIX.1-2008.~~
This assumes ASCII and 32 bit ints.
[Answer]
# [Ruby](https://www.ruby-lang.org/), 82 bytes
```
->i{1+((0>r=i.ord-33)?r%5:"bc7xdutvz4ind3bwqf6mcu5vxiahnmlfs93c".to_i(36)>>2*r&3)}
```
[Try it online!](https://tio.run/##KypNqvyfZvtf1y6z2lBbQ8PArsg2Uy@/KEXX2FjTvkjV1EopKdm8IqW0pKzKJDMvxTipvDDNLDe51LSsIjMxIy83J63Y0jhZSa8kPz5Tw9hM087OSKtIzViz9n@BQlq0vUEsF5guhNKJEFpFH8qvgtBKCkqx/wE "Ruby – Try It Online")
[Answer]
# CJam, 125 bytes
```
q_" "={;5}{"`1234567890-=~!@#$%^&*()_+qwertyuiop[]\QWERTYUIOP{}|asdfghjkl;'ASDFGHJKL:\"    zxcvbnm,./ZXCVBNM<>?    "\#26/1+}?
```
---
### Explanation
```
q                          e# read input
 _" "=                     e# decide if the input is a space
      {;5}                 e# if it is, push 5
          {"..."\#26/1+}?  e# if it isn't, push the correct row
```
[Answer]
# SpecBAS - 178 bytes
```
1 a$="~`!1@2#3$4%5^6&7*8(9)0-_+=qQwWeErRtTyYuUiIoOpP{[}]|\aaaaAsSdDfFgGhHjJkKlL:;'"#34#13"zzzzzzzZxXcCvVbBnNmM<,>.?/"+" "*26
2 INPUT k$: IF k$="" THEN k$=#13
3  ?CEIL(POS(k$,a$)/26)
```
I used a long string where each row is 26 characters long (#34 is code for double quote and #13 is code for return).
Then print the result of rounding position/26.
[Answer]
# C#6, 201 bytes
Nothing special here. I found it cheaper to just write both cases rather than use ToUpper() due to the string's fixed width.
```
using C=System.Console;class P{static void Main(string[]a)=>C.Write("`1234567890-=~!@#$%^&*()_+qwertyuiop[]\\QWERTYUIOP{}|asdfghjkl;'\raASDFGHJKL:\"\nazxcvbnm,./zzzZXCVBNM<>?zzz ".IndexOf(a[0])/26+1);}
```
Indented:
```
using C=System.Console;
class P{
    static void Main(string[]a)=>
        C.Write("`1234567890-=~!@#$%^&*()_+qwertyuiop[]\\QWERTYUIOP{}|asdfghjkl;'\raASDFGHJKL:\"\nazxcvbnm,./zzzZXCVBNM<>?zzz ".IndexOf(a[0])/26+1);
}
```
[Answer]
# Python 2, 146 bytes
```
e="\n";lambda x:("`1234567890-=~!@#$%^&*()_+qwertyuiop[]\\QWERTYUIOP{}|asdfghjkl;'ASDFGHJKL:\""+e*4+"zxcvbnm,./ZXCVBNM<>?"+e*13+" ").index(x)/26+1
```
[Answer]
# Excel, 132 bytes
`=INT((FIND(A1,"`1234567890-=~!@#$%^&*()_+qwertyuiop[]\QWERTYUIOP{}|asdfghjkl;'ASDFGHJKL:""aaa
zxcvbnm,./ZXCVBNM<>?zzzzzz ")-1)/26)+1`
Attempts to use the case in-sensitive `SEARCH()` instead of `FIND()` revealed that Excel matches `~`, `*` and `?` to `(tick). The matching of`?`means we can't use`SEARCH()`, which would have shaved a massive 5 bytes...
]