You have some core problems in your regex, the main one being the ^ that negates your character class. So instead of [^0-9] matching any digit, it matches anything but a digit. Also, the g modifier doesn't exist in PHP (preg_replace() replaces globally and you can use preg_match_all() to match expressions globally).
You'll want to use a regex like /@\[(\d+)\]/ to match (with a group) all of the digits between @[ and ].
To do this globally on a string in PHP, use preg_match_all():
preg_match_all('/@\[(\d+)\]/', 'Hi @[123456789] :)', $matches);
var_dump($matches);
However, your code would be cleaner if you didn't rely on a match group (\d+). Instead you can use "lookarounds" like: (?<=@\[)\d+(?=\]). Also, if you will only have one digit per string, you should use preg_match() not preg_match_all().
Note: I left the example vague and linked to lots of documentation so you can read/learn better. If you have any questions, please ask. Also, if you want a better explanation on the regular expressions used (specifically the second one with lookarounds), let me know and I'll gladly elaborate.
^in your character class looks for the negative (so[^0-9]looks for anything but a digit). Real answer incoming..../@\[[0-9_]+\]/g(remove the underscore if there shouldn't be any within the square brackets).