Для
str = "Oracle Enterprise Linux 5-X86_64 9"
Вы сказали, что
r = /oracle[ a-z]* ([0-9])(?:.* )*?([0-9])$/i
"соответствует всей строке" (я добавил i
в конце). Как
str[r]
#=> "Oracle Enterprise Linux 5-X86_64 9"
мы видим, что это правда, но нам нужно содержимое групп захвата.
$1 #=> "5"
$2 #=> "9"
Как вы видите, вы просто пренебрегали захватом слова в начале. Поэтому вы можете написать регулярное выражение таким образом. (Я сделал несколько небольших уточнений.)
r = /
(\p{L}+) # match one or more letters in capture group 1
\D* # match zero or more characters other than digits
(\d) # match a digit in capture group 2
.+ # match one or more characters
(\d+) # match one or more digits in capture group 3
\z # match the end of the string
/x # free-spacing regex definition mode
str.match(r)
$1 #=> "Oracle"
$2 #=> "5"
$3 #=> "9"
Метод
String # scan предоставляет лучший способ извлечения нужных строк. (Смотрите документ о том, как метод обрабатывает группы захвата.)
str.scan(r).first
#=> ["Oracle", "5", "9"]