string1[/(?<= ).*?(?=\.lname\b)/]
#=> "name is fname"
(?<= )
- это положительный взгляд за , который требует, чтобы первому сопоставленному символу предшествовал пробел, но этот пробел не является частью совпадения.
(?=\.lname\b)
является положительным прогнозом , для которого требуется, чтобы за последним сопоставленным символом сразу следовала строка ".lname"
1
, за которым следует разрыв слова (\b
), но эта строка не является частью совпадения. Это гарантирует, например, что "\.lnamespace"
не совпадает. Если это должно быть найдено, удалите \b
.
.*?
соответствует нулю больше символов (.*
), без жадности (?
). (По умолчанию это совпадения жадные .) Нежадный классификатор имеет следующий эффект:
"my name is fname.lname and fname.lname"[/(?<= ).*(?=\.lname\b)/]
#=> "name is fname.lname and fname"
"my name is fname.lname and fname.lname"[/(?<= ).*?(?=\.lname\b)/]
#=> "name is fname"
Другими словами, не жадное (жадное) совпадение соответствует первому (последнему) вхождению ".lname"
в строке.
В качестве альтернативы это можно записать с группой захвата и без обходных путей:
string1[/ (.*?)\.lname\b/, 1]
#=> "name is fname"
Это регулярное выражение гласит: «сделайте пробел, за которым следуют ноль или более символов, сохраненные в группе захвата 1, за которыми следует строка ".name"
, за которой следует разрыв слова. Используется форма String # [] с двумя аргументами - ссылкой на группу захвата.
Далее следует еще один путь.
string1[(string1 =~ / /)+1..(string1 =~ /\.lname\b/)-1]
#=> "name is fname"
1 Точка в ".lname"
должна быть экранирована, поскольку неэкранированный период в регулярном выражении (кроме класса символов) соответствует любому символу.