module Corefines::String::ToRe

@!method #to_re(opts = {})

Returns a regular expression represented by this string.

@example
  '/^foo/'.to_re                  # => /^foo/
  '/foo/i'.to_re                  # => /foo/i
  'foo'.to_re                     # => nil

  'foo'.to_re(literal: true)      # => /foo/
  '^foo*'.to_re(literal: true)    # => /\^foo\*/

  '/foo/'.to_re(detect: true)     # => /foo/
  '$foo/'.to_re(detect: true)     # => /\$foo\//
  ''.to_re(detect: true)          # => nil

  '/foo/'.to_re(multiline: true)  # => /foo/m

@note This method was renamed from +to_regexp+ to +to_re+ due to bug
  in MRI, see {#11117}[https://bugs.ruby-lang.org/issues/11117].

@param opts [Hash] options
@option opts :literal [Boolean] treat meta characters and other regexp
        codes as just a text. Never returns +nil+. (default: false)
@option opts :detect [Boolean] if string starts and ends with a slash,
        treat it as a regexp, otherwise interpret it literally.
        (default: false)
@option opts :ignore_case [Boolean] same as +/foo/i+. (default: false)
@option opts :multiline [Boolean] same as +/foo/m+. (default: false)
@option opts :extended [Boolean] same as +/foo/x+. (default: false)

@return [Regexp, nil] a regexp, or +nil+ if +:literal+ is not set or
  +false+ and this string doesn't represent a valid regexp or is empty.

Public Instance Methods

to_re(opts = {}) click to toggle source
# File lib/corefines/string.rb, line 444
def to_re(opts = {})

  if opts[:literal]
    content = ::Regexp.escape(self)

  elsif self =~ %r{\A/(.*)/([imxnesu]*)\z}
    content, inline_opts = $1, $2
    content.gsub! '\/', '/'

    { ignore_case: 'i', multiline: 'm', extended: 'x' }.each do |k, v|
      opts[k] ||= inline_opts.include? v
    end if inline_opts

  elsif opts[:detect] && !self.empty?
    content = ::Regexp.escape(self)
  else
    return
  end

  options = 0
  options |= ::Regexp::IGNORECASE if opts[:ignore_case]
  options |= ::Regexp::MULTILINE if opts[:multiline]
  options |= ::Regexp::EXTENDED if opts[:extended]

  ::Regexp.new(content, options)
end