捕获匹配项前后的字符

Capture characters before and after matching term

我正在编写一个 Ruby 脚本,用于在文本文件中搜索马萨诸塞州城镇的名称。我需要捕获任何匹配项周围的一定数量的字符并将它们保存为字符串。

例如,下面的段落包含单词 "Springfield." 我需要捕获单词 Springfield 及其两侧的 20 个字符,并将整个摘录保存为字符串,节选.

This is a sample passage that includes the term Springfield. The sample passage goes on to describe the population, demographics and tourist attractions in the community etc.

结果应该是这样的:

excerpt = "t includes the term Springfield. The sample passage"

试试这个:

text = "This is a sample passage that includes the term Springfield. The sample passage goes on to describe the population, demographics and tourist attractions in the community etc."

search = "Springfield"
i = text.index(search)    

excerpt = text[i-20..i+20+search.size]
# => "t includes the term Springfield. The sample passage "

我认为这与您要找的很接近,但是您没有给出所有规则。特别是你没有说如果 "Springfield" 前面或后面少于 20 个字符会发生什么。 (我假设最多 20 个。)此外,您还没有说 "Springfield" 是否可以成为较长单词的一部分。我假设它不能,但如果不是这种情况,只需从正则表达式中删除单词 breaks (\b) 。另外,我用 join 编辑了 ':' 只是为了显示联接的位置,但您当然可以将其更改为 ''

def extract(str)
  str.scan(/.{,20}\bSpringfield\b.{,20}/).join(':')
end

extract(text)
  #=> "t includes the term Springfield. The sample passage" 
extract("a Springfield 123456789012345678 Springfield b")
  #=> "a Springfield 123456789012345678 :Springfield b" 
extract("a bSpringfield 123456789012345678 Springfield b")
  #=> " 123456789012345678 Springfield b" 

如果在第二个示例中,如果您希望显示第二个 Springfield 之前的(最多)20 个字符,您可以使用 String#scan 形式的正向先行,它采用一块。这里的块变量 m 是一个数组,其中包含两个捕获组的值(即 m => [,]。请注意,当提供一个块时,scan returns 原始字符串,因此有必要将匹配结果捕获到一个数组中(此处 a)。

def extract(str)
  a = []
  str.scan(/(.{,20}\bSpringfield)\b(?=(.{,20}))/) { |m| a << m.join }
  a.join(':')
end

extract("a Springfield 123456789012345678 Springfield b")
  #=> "a Springfield 123456789012345678 : 123456789012345678 Springfield b"