If you wrote it like:

    data.gsub!(/#{placeholder}\s+/) { |match| placeholder + input + ' ' * (match.length - input.length) }

You could call it a bit easier:

    string_sub(classes, 'ZZZZ', 'http://0.0.0.0')

If you have to preserve the spacing, you should probably also validate the length of `input` as well (make sure it is not longer than the `match` param in the gsub block).