Насколько я понимаю, при наличии строки вы хотите извлечь все подстроки, имеющие следующие свойства:
- подстроке предшествует запятая или начинается строка, после которой следует запятая или конец строки;
- подстрока содержит только цифры и заглавные буквы;
- подстрока содержит хотя бы одну цифру;
- подстрока содержит хотя бы одну заглавную букву; и
- подстрока не может заканчиваться строкой
"km"
.
Тестовая строка следующая.
str = "65101km,Sedan,Manual,18131A,FWD,Used,5.5L/100km,Toyota,camry,SE," +
"{AC, Heated Seats, Heated Mirrors, Keyless Entry},2010,208A1,28km1"
Обратите внимание, что я добавил строку, приведенную в вопросе, с ",208A1,28km1"
.
Вы можете извлечь нужные подстроки, используя метод String # scan со следующим регулярным выражением.
r = /
(?<=\A|,) # match the beginning of the string or a comma in a positive lookbehind
[\p{Upper}\d] # match a digit or uppercase letter in character class
* # perform above match zero or more times
(?: # begin a non-capture group
\d # match a digit
\p{Upper} # match an uppercase letter
| # or
\p{Upper} # match an uppercase letter
\d # match one or more digits
) # end non-capture group
[\p{Upper}\d] # match a digit or uppercase letter in character class
* # perform above match zero or more times
(?<!km) # do not match 'km' (negative lookbehing)
(?=,|\z) # match a comma or end of the string (positive lookahead)
/x # free-spacing regex definition mode
str.scan(r)
#=> ["18131A", "208A1"]
Кроме того, вы можете сделать это в четыре простых шага.
str.split(',').select do |s| s.match?(/\A\p{Alnum}+\z/) &&
s.match?(/\p{Alpha}/) &&
s.match?(/\p{Digit}/) &&
!s.end_with?("km")
end
#=> ["18131A", "208A1"]
Документацию для \p{}
конструкций можно найти, выполнив поиск по этому же адресу в Regexp . Они аналогичны классам скобок POSIX , которые описаны в одном файле.
Регулярное выражение записывается условно (то есть, не в режиме свободного пробела) следующим образом. Я также заменил \p{Upper}
на его сокращение \p{Lu}
.
r = /(?<=\A|,)[\p{Lu}\d]*(?:\d\p{Lu}|\p{Lu}\d)[\p{Lu}\d]*(?<!km)(?=,|\z)/