class RuboCop::Cop::Style::RedundantRegexpArgument
‘foo’.sub!(‘f’, ‘x’)
‘foo’.sub(‘f’, ‘x’)
‘foo’.start_with?(‘f’)
‘foo’.split(‘f’)
‘foo’.scan(‘f’)
‘foo’.rpartition(‘f’)
‘foo’.partition(‘f’)
‘foo’.gsub!(‘f’, ‘x’)
‘foo’.gsub(‘f’, ‘x’)
‘foo’.byterindex(‘f’)
‘foo’.byteindex(‘f’)
# good
’foo’.sub!(/f/, ‘x’)
‘foo’.sub(/f/, ‘x’)
‘foo’.start_with?(/f/)
‘foo’.split(/f/)
‘foo’.scan(/f/)
‘foo’.rpartition(/f/)
‘foo’.partition(/f/)
‘foo’.gsub!(/f/, ‘x’)
‘foo’.gsub(/f/, ‘x’)
‘foo’.byterindex(/f/)
‘foo’.byteindex(/f/)
# bad
@example
a deterministic regexp to a string.
Identifies places where argument can be replaced from
def determinist_regexp?(regexp_node)
def determinist_regexp?(regexp_node) DETERMINISTIC_REGEX.match?(regexp_node.source) end
def on_send(node)
def on_send(node) return unless (regexp_node = node.first_argument) return unless regexp_node.regexp_type? return if !regexp_node.regopt.children.empty? || regexp_node.content == ' ' return unless determinist_regexp?(regexp_node) prefer = preferred_argument(regexp_node) message = format(MSG, prefer: prefer, current: regexp_node.source) add_offense(regexp_node, message: message) do |corrector| corrector.replace(regexp_node, prefer) end end
def preferred_argument(regexp_node)
def preferred_argument(regexp_node) new_argument = replacement(regexp_node) if new_argument.include?('"') new_argument.gsub!("'", "\\\\'") quote = "'" else quote = '"' end "#{quote}#{new_argument}#{quote}" end
def replacement(regexp_node)
def replacement(regexp_node) regexp_content = regexp_node.content stack = [] chars = regexp_content.chars.each_with_object([]) do |char, strings| if stack.empty? && char == '\\' stack.push(char) else strings << "#{stack.pop}#{char}" end end chars.map do |char| char = char.dup char.delete!('\\') unless STR_SPECIAL_CHARS.include?(char) char end.join end