我有一个字符串:
string1 = "my name is fname.lname and i live in xyz. my lname is not common"
我想从string1
中提取一个子字符串,该子字符串是第一个空白空间" "
和".lname"
之间的任何东西。在上述情况下,答案应为“ fname.lname”`。
答案 0 :(得分:1)
string1[/(?<= ).*?(?=\.lname\b)/]
#=> "name is fname"
(?<= )
是一个正向后看,要求匹配的第一个字符后紧跟一个空格,但该空格不是匹配项的一部分。
(?=\.lname\b)
是正向超前,要求最后一个匹配的字符后紧跟字符串".lname"
1
,其后跟一个分词符(\b
),但该字符串不是匹配项的一部分。例如,这可以确保"\.lnamespace"
不匹配。如果应该匹配,请删除\b
。
.*?
与非零字符(.*
)匹配另外零个字符(?
)。 (默认情况下,匹配为 greedy 。)非贪婪限定符具有以下作用:
"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"
中的句点,因为正则表达式中的未转义的句点(字符类除外)与 any 字符匹配。 >