I've got a data file that looks like this:
Things
├── Foo
│ ├── 1. Item One
│ ├── 2. Item Two
│ ├── 3. Item Three
│ ├── 4. Item Four
│ ├── 5. Item Five
│ └── 6. Item Six
├── Bar
│ ├── 1. Item Seven
│ ├── 2. Item Eight
│ ├── 3. Item Nine
What I'm trying to do is find a certain string, the number associated with it, and also the subheading that is a part of ('Foo' or 'Bar')
It's pretty easy to grab the item and the number:
str = "Item One"
data.each_line do |line|
if line =~ /#{str}/
/(?<num>\d).\s(?<item>.*)/ =~ line
end
end
But I'm not sure how to get the subheading. What I was thinking is that once I found the line, I could count up from that point using the number. Is there a readlines or a seek command or some such that could do this?
Appreciate the help!
I came up with below, this seems to work:
data = <<-EOF
Things
├── Foo
│ ├── 1. Item One
│ ├── 2. Item Two
│ ├── 3. Item Three
│ ├── 4. Item Four
│ ├── 5. Item Five
│ └── 6. Item Six
├── Bar
│ ├── 1. Item Seven
│ ├── 2. Item Eight
│ ├── 3. Item Nine
EOF
str = "Item One"
data.lines.each_with_index do |line, i|
if /(?<num>\d)\.\s+#{str}/ =~ line
/(?<var>\w+)/ =~ data.lines[i - (n = $~[:num]).to_i]
p [n, str, var] # ["1", "Item One", "Foo"]
end
end
(n = $~[:num])
is needed to store the captured value of num
from
if /(?<num>\d)\.\s+#{str}/ =~ line
into a variable (say n
) as last match data, represented by global variable $~
, will get overwritten during the next regex match taking place in statement
/(?<var>\w+)/ =~ data.lines[i - (num = $~[:num]).to_i]
and unless we store it for later use we will lose the captured value num
.
Here's another way (using @Wand's data
):
LAZY_T = "├── "
target = "Item Four"
str = data.split(/\n#{LAZY_T}/).find { |s| s =~ /\b#{target}\b/ }
str && [str[/[a-zA-Z]+/], str[/(\d+)\.\s#{target}\b/,1]]
#=> ["Foo", "4"]
The first line pulls out the applicable part of the string ("Foo"
or "Bar"
), if there is one. The second line extracts the two desired elements.
Note:
LAZY_T.split('').map(&:ord)
#=> [9500, 9472, 9472, 32]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With