0

I'm writing a method where I need to exclude lines that contain this "{" and this "}" characters. I'm using the StringScanner Class with the exists? method. The args parameter is an array of strings.

def body_content (args)
    body_lines = []
    args.each_with_index { |x, i|
      x.reset
      if !x.exist?(Regexp.new("{")) && !x.match?(Regexp.new("^ +.*")) 
        body_lines << "Add space at the beginning of line #{i + 1}"
      elsif !x.exist?(Regexp.new("}")) && !x.match?(Regexp.new("^ +.*")) 
        body_lines << "Add space at the beginning of line #{i + 1}"
      end
    }
    body_lines
  end

The end result should be that my body_lines array should only include lines that do not contain { or } and that do not have space in the beginning. I'm succeeding with my second task (adding lines that do not have space in the beginning), however, I'm not being able to exclude lines that contain the curly brackets. Am I not seeing something?

8
  • Welcome to SO! Please see "How to Ask", "Stack Overflow question checklist" and "MCVE" and all their linked pages. Provide the minimal code and input to demonstrate the problem, along with your desired output. Commented Apr 29, 2020 at 20:13
  • 1
    In Ruby it's idiomatic to use literals to define patterns, rather than Regexp.new(...). For instance, don't use Regexp.new("{"), instead use /{/. It reduces visual-noise. Commented Apr 29, 2020 at 20:19
  • 1
    Can you give some sample input and some sample output? The way you've expressed this here is really verbose and misleading. As The Tin Man says, this would be way shorter with things like x.exist?(/}/) Commented Apr 29, 2020 at 20:24
  • 2
    Welcome to Stack Overflow. When you create a new question and the system tells you that your title is not unique or descriptive enough then please do not add something like "[Ruby]" to the end of it. That's a tag, and you have already tagged your post with ruby. I attempted to remove it from the title but the system rejects the post with this title. Please change your title to an appropriately descriptive one. You can read about titles at stackoverflow.com/help/how-to-ask. Commented Apr 29, 2020 at 20:24
  • 1
    Compare regex101.com/r/5vIhL1/3 and regex101.com/r/5vIhL1/4. They accomplish the same thing when checking for leading spaces but the second is less efficient and will cause the Regex engine to waste time, slowing your code if you're working on long strings or in a loop, and especially for long strings in a loop. Commented Apr 29, 2020 at 20:32

1 Answer 1

2

Your function could look like this:

class MyRegExp
    def body_content (args)
        body_lines = []
        args.each_with_index { |x, i|
            puts "x is #{x}"
          if !x.match(Regexp.new("{")) && !x.match(Regexp.new("^ +.*")) 
            body_lines << "Add space at the beginning of line #{i + 1}"
          elsif !x.match(Regexp.new("}")) && !x.match(Regexp.new("^ +.*")) 
            body_lines << "Add space at the beginning of line #{i + 1}"
          end
        }
        body_lines
      end
end

And you can test it like this:

require_relative '../my_regexp'

RSpec.describe MyRegExp do
    context "with { and leading space" do
        it "should add these strings to the output" do 
            args = []
            args << " This string has a leading space"
            args << "This string contains { and }"
            args << "This string contains neither"
            res = MyRegExp.new.body_content(args)
            expect(res).to include "Add space at the beginning of line 3"
            expect(res).not_to include " This string has a leading space"
            expect(res).not_to include "This string contains { and }"
        end
    end
end

If I've understood what you're trying to accomplish - the tests pass:

➜  test_ruby_scripts rspec
x is  This string has a leading space
x is This string contains { and }
x is This string contains neither
.

Finished in 0.00231 seconds (files took 0.07841 seconds to load)
1 example, 0 failures

You don't need this StringScanner class - I don't even know what it should do - but Ruby has built in functions to check if a string contains a RegExp.

I think this is a simplified version of your function:

class MyRegExp
    def body_content (args)
        body_lines = []
        args.each_with_index { |x, i|
            puts "x is #{x}"
            body_lines << "Add space at the beginning of line #{i + 1}" if !x.match(/^ +.*({|})+.*/)
        }
        body_lines
    end
end
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.