I\'m deeply puzzled by the way grep seems to parse a regex:
$ echo \"@NS500287\" | grep \'^@NS500[0-9]{3}\'
#nothing
$ echo \"@NS500287\" | grep \'^@NS500[0-
The answer relates to the difference between Basic Regular Expressions (BREs) and Extended ones (EREs).
In BRE mode (i.e. when you call grep with no argument to specify otherwise), the { and } are interpreted as literal characters. Escaping them with \ means that they are to be interpreted as a number of instances of the previous pattern.
If you were to use grep -E instead (ERE mode), you would be able to use { and } without escaping to refer to the count. In ERE mode, escaping the braces causes them to be interpreted literally instead.