class RuboCop::Cop::Style::RegexpLiteral
This cop enforces using // or %r around regular expressions.
@example EnforcedStyle: slashes (default)
# bad snake_case = %r{^[\dA-Z_]+$} # bad regex = %r{ foo (bar) (baz) }x # good snake_case = /^[\dA-Z_]+$/ # good regex = / foo (bar) (baz) /x
@example EnforcedStyle: percent_r
# bad snake_case = /^[\dA-Z_]+$/ # bad regex = / foo (bar) (baz) /x # good snake_case = %r{^[\dA-Z_]+$} # good regex = %r{ foo (bar) (baz) }x
@example EnforcedStyle: mixed
# bad snake_case = %r{^[\dA-Z_]+$} # bad regex = / foo (bar) (baz) /x # good snake_case = /^[\dA-Z_]+$/ # good regex = %r{ foo (bar) (baz) }x
@example AllowInnerSlashes: false (default)
# If `false`, the cop will always recommend using `%r` if one or more # slashes are found in the regexp string. # bad x =~ /home\// # good x =~ %r{home/}
@example AllowInnerSlashes: true
# good x =~ /home\//
Constants
- MSG_USE_PERCENT_R
- MSG_USE_SLASHES
Public Instance Methods
autocorrect(node)
click to toggle source
# File lib/rubocop/cop/style/regexp_literal.rb, line 99 def autocorrect(node) lambda do |corrector| correct_delimiters(node, corrector) correct_inner_slashes(node, corrector) end end
on_regexp(node)
click to toggle source
# File lib/rubocop/cop/style/regexp_literal.rb, line 91 def on_regexp(node) if slash_literal?(node) check_slash_literal(node) else check_percent_r_literal(node) end end
Private Instance Methods
allow_inner_slashes?()
click to toggle source
# File lib/rubocop/cop/style/regexp_literal.rb, line 149 def allow_inner_slashes? cop_config['AllowInnerSlashes'] end
allowed_mixed_percent_r?(node)
click to toggle source
# File lib/rubocop/cop/style/regexp_literal.rb, line 136 def allowed_mixed_percent_r?(node) style == :mixed && node.multiline? || contains_disallowed_slash?(node) end
allowed_mixed_slash?(node)
click to toggle source
# File lib/rubocop/cop/style/regexp_literal.rb, line 125 def allowed_mixed_slash?(node) style == :mixed && node.single_line? && !contains_disallowed_slash?(node) end
allowed_percent_r_literal?(node)
click to toggle source
# File lib/rubocop/cop/style/regexp_literal.rb, line 130 def allowed_percent_r_literal?(node) style == :slashes && contains_disallowed_slash?(node) || style == :percent_r || allowed_mixed_percent_r?(node) end
allowed_slash_literal?(node)
click to toggle source
# File lib/rubocop/cop/style/regexp_literal.rb, line 120 def allowed_slash_literal?(node) style == :slashes && !contains_disallowed_slash?(node) || allowed_mixed_slash?(node) end
calculate_replacement(node)
click to toggle source
# File lib/rubocop/cop/style/regexp_literal.rb, line 218 def calculate_replacement(node) if slash_literal?(node) ['%r', ''].zip(preferred_delimiters).map(&:join) else %w[/ /] end end
check_percent_r_literal(node)
click to toggle source
# File lib/rubocop/cop/style/regexp_literal.rb, line 114 def check_percent_r_literal(node) return if allowed_percent_r_literal?(node) add_offense(node, message: MSG_USE_SLASHES) end
check_slash_literal(node)
click to toggle source
# File lib/rubocop/cop/style/regexp_literal.rb, line 108 def check_slash_literal(node) return if allowed_slash_literal?(node) add_offense(node, message: MSG_USE_PERCENT_R) end
contains_disallowed_slash?(node)
click to toggle source
# File lib/rubocop/cop/style/regexp_literal.rb, line 141 def contains_disallowed_slash?(node) !allow_inner_slashes? && contains_slash?(node) end
contains_slash?(node)
click to toggle source
# File lib/rubocop/cop/style/regexp_literal.rb, line 145 def contains_slash?(node) node_body(node).include?('/') end
correct_delimiters(node, corrector)
click to toggle source
# File lib/rubocop/cop/style/regexp_literal.rb, line 167 def correct_delimiters(node, corrector) replacement = calculate_replacement(node) corrector.replace(node.loc.begin, replacement.first) corrector.replace(node.loc.end, replacement.last) end
correct_inner_slashes(node, corrector)
click to toggle source
# File lib/rubocop/cop/style/regexp_literal.rb, line 173 def correct_inner_slashes(node, corrector) regexp_begin = node.loc.begin.end_pos inner_slash_indices(node).each do |index| start = regexp_begin + index corrector.replace( range_between( start, start + inner_slash_before_correction(node).length ), inner_slash_after_correction(node) ) end end
inner_slash_after_correction(node)
click to toggle source
# File lib/rubocop/cop/style/regexp_literal.rb, line 206 def inner_slash_after_correction(node) inner_slash_for(calculate_replacement(node).first) end
inner_slash_before_correction(node)
click to toggle source
# File lib/rubocop/cop/style/regexp_literal.rb, line 202 def inner_slash_before_correction(node) inner_slash_for(node.loc.begin.source) end
inner_slash_for(opening_delimiter)
click to toggle source
# File lib/rubocop/cop/style/regexp_literal.rb, line 210 def inner_slash_for(opening_delimiter) if ['/', '%r/'].include?(opening_delimiter) '\/' else '/' end end
inner_slash_indices(node)
click to toggle source
# File lib/rubocop/cop/style/regexp_literal.rb, line 189 def inner_slash_indices(node) text = node_body(node, include_begin_nodes: true) pattern = inner_slash_before_correction(node) index = -1 indices = [] while (index = text.index(pattern, index + 1)) indices << index end indices end
node_body(node, include_begin_nodes: false)
click to toggle source
# File lib/rubocop/cop/style/regexp_literal.rb, line 153 def node_body(node, include_begin_nodes: false) types = include_begin_nodes ? %i[str begin] : %i[str] node.each_child_node(*types).map(&:source).join end
preferred_delimiters()
click to toggle source
# File lib/rubocop/cop/style/regexp_literal.rb, line 162 def preferred_delimiters config.for_cop('Style/PercentLiteralDelimiters') \ ['PreferredDelimiters']['%r'].split(//) end
slash_literal?(node)
click to toggle source
# File lib/rubocop/cop/style/regexp_literal.rb, line 158 def slash_literal?(node) node.loc.begin.source == '/' end