以下是提取所需子字符串(如果存在)的两种方法。我们给出以下内容。
str = "1;abc;111;10-nov-2017 2;abc;222;11-nov-2017 3;abc;333;12-nov-2017"
before_str = "abc;"
date_str = ";11-nov-2017"
我假设的date_str
值出现在str
最多一次。
#1使用正则表达式
r =/
.* # match any number of characters greedily
#{before_str} # match the content of the variable 'before_str'
(.*) # match any number characters greedily, in capture group 1
#{date_str} # match the content of the variable 'date_str'
/x # free-spacing regex definition mode
#=> /.*abc;(.*);11-nov-2017/x
str[r,1]
#=> "222"
这里的关键是.*
在正则表达式的开始。作为一个贪婪的匹配,它会导致下一个匹配成为"abc;"
(的值before_str
)的前一个(值为date_str
)的最后一个实例。
#2确定用于期望subtring的开始和结束索引
idx_date = str.index(date_str)
#=> str.index(";11-nov-2017") => 31
idx_before = str.rindex(before_str, idx_date-before_str.size)
#=> str.rindex("abc;", 27) => 24
str[idx_before + before_str.size..idx_date-1]
#=> str[24+4..31-1] => str[28..30] => "222"
如果任idx_date
或idx_before
被nil
,nil
将被返回,并且最后一个表达式不进行评估。
查看String#rindex,特别是可选的第二个参数的功能。
(有人可能会写str[idx_before + date_str.before...idx_date]
,但我发现在范围内使用三个点的是错误的潜在来源,所以我总是用两个点。)
和你尝试过什么 – revo
我试过数据[/ #{ 'ABC;'}。(*?)#{'; 11-nov1017'}/m,1]但它的返回; 111; 10-nov-2017 2; abc; 222;即第一个abc和11-nov1017之间的数据 – Imran