如何在两个字符/子字符串之间提取子字符串

时间:2019-03-13 00:31:10

标签: ruby string

我有一个字符串:

string1 = "my name is fname.lname and i live in xyz. my lname is not common"

我想从string1中提取一个子字符串,该子字符串是第一个空白空间" "".lname"之间的任何东西。在上述情况下,答案应为“ fname.lname”`。

1 个答案:

答案 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 字符匹配。