That is because in your pattern, it also matches 3xx where x can be any digit and not just 0. If you change your pattern to match 1xx, 2xx and 300 then it will return the result as you intended, i.e.:
/^([12][0-9][0-9]|300)\s.*/g
See example below:
const str = `
99 Apple
100 banana
101 pears
200 wheat
220 rice
300 corn
335 raw maize
399 barley
400 green beans
`;
const matches = str.split('\n').filter(s => s.match(/^([12][0-9][0-9]|300)\s.*/));
console.log(matches);
However, using regex to match numerical values might not be as intuitive than simply extracting any numbers from a string, converting them to a number and then simply using mathematical operations. We can use the unary + operator to convert the matched number-like string as such:
const str = `
99 Apple
100 banana
101 pears
200 wheat
220 rice
300 corn
335 raw maize
399 barley
400 green beans
`;
const entries = str.split('\n').filter(s => {
const match = s.match(/\d+\s/);
return match !== null && +match[0] >= 100 & +match[0] <= 300;
});
console.log(entries);