InputUsername
InputUsername

Reputation: 440

Ruby: check if a string is formatted in a very specific way

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

Answers (2)

Cary Swoveland
Cary Swoveland

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

walid toumi
walid toumi

Reputation: 2272

Maybe this:

[ ]+#{6}[\n ]+#{3}[ ]+#{3}[\n ]+(?>#[ ]+#[\n\s]+)+#{3}[ ]+#{3}[\n\s]+#{6}\s*

Demo

Upvotes: 1

Related Questions