Reputation: 440
I'm trying to write a piece of code that tells the user if a string is formatted in a specific way. The format looks like this (it's a circle):
######\n
### ###\n
# #\n
# #\n
# #\n
# #\n
# #\n
### ###\n
######\n
\n
The newlines are included for clarity; the # character may be any character from an existing character class.
What I want to do is check if a string (from a file) contains one or more of these "circles". Multiple circles should be seperated like this:
# #\n
### ###\n
######\n
\n
######\n
### ###\n
# #\n
So this is what I've tried:
isCircle = "( #{get_i}{6}\n"
isCircle += " #{get_i}{3} #{get_i}{3}\n"
isCircle += " #{get_i} #{get_i}\n"
isCircle +=("#{get_i} #{get_i}\n"*3)
isCircle += " #{get_i} #{get_i}\n"
isCircle += " #{get_i}{3} #{get_i}{3}\n"
isCircle = " #{get_i}{6}\n\n?)*"
isCircle = Regexp.new(isCircle)
(get_i is a method that returns the aforementioned character class, correctly escaped and everything)
However, when testing this against an incorrect input string, it still tells me there's a match. What am I doing wrong and how can I correctly perform the match?
Upvotes: 0
Views: 367
Reputation: 110675
Is this what you want to do?
Suppose you wish to search for this pattern:
pattern =
%{ ######
### ###
# #
# #
# #
# #
# #
### ###
######
}
in a text file whose contents have been read into this string:
str =
%{###
##
######
### ###
# #
# #
# #
# #
# #
### ###
######
#######
######
######
### ###
# #
# #
# #
# #
# #
### ###
######
###
}
Just use String#scan:
puts str.scan(pattern).join("\n")
######
### ###
# #
# #
# #
# #
# #
### ###
######
######
### ###
# #
# #
# #
# #
# #
### ###
######
If you instead want the line offsets of str
where the pattern begins:
sarr = str.lines
parr = pattern.lines
prows = parr.size
(sarr.size-prows+1).times.select { |i| sarr[i,prows] == parr }
#==> [2, 13]
Upvotes: 0
Reputation: 2272
Maybe this:
[ ]+#{6}[\n ]+#{3}[ ]+#{3}[\n ]+(?>#[ ]+#[\n\s]+)+#{3}[ ]+#{3}[\n\s]+#{6}\s*
Upvotes: 1