It seems "pretty convoluted" because built-in functions are designed to handle the general case, not just a very specific case. The language would be pretty limiting otherwise. What if the string had more than one integer?
button = "There are 314 buttons, 10 are green and 20 are blue";
button // StringCases[d : DigitCharacter .. :> ToExpression[d]]
(* {314, 10, 20} *)
That is why it returns a List
of the matches. You can then extract whichever number you need using Part
.
If you just need to handle a specific case of extracting one integer then write a function to do that.
(* Returns the first one by default *)
extractInteger[s_String, position_Integer : 1] :=
s // StringCases[d : DigitCharacter .. :> ToExpression[d]] //
Flatten // Part[#, position] &
extractInteger[button]
(* 314 *)
extractInteger[button, 3]
(* 20 *)