简体   繁体   中英

Smart conversion of double to single quotes in ruby

Problem

In a source file, I have a large number of strings. Some with interpolation, some with special symbols and some with neither.

I am trying to work out if I can replace the simple strings' double quotes with single quotes whilst leaving double quotes for the interpolated and special symbol strings. I would then run this conversion on one or more source code files.

I imagine there is probably a nice regex for this, but I can't quite formulate it.

Example - Code

Imagine the following code:

def myfunc(var, var2 = "abc")
  s = "something"
  puts "a simple string"
  puts "string with a single ' quote"
  puts "string with a newline \n"  
  puts "my #{var}"
end

Example - Result

I would like to turn it into this:

def myfunc(var, var2 = 'abc')
  s = 'something'
  puts 'a simple string'
  puts "string with a single ' quote"
  puts "string with a newline \n"  
  puts "my #{var}"
end

If anyone has any ideas I'd be very grateful!

Assuming that you can read your string from your file by yourself into an array strings :

strings = [ "\"a simple string\"",
            "\"string with a single ' quote\"",
            "\"string with a newline \n\""
            "\"my \#{var}\"" ]

then we would eval them to see how they behave:

$SAFE = 4
single_quoted_when_possible = strings.map { |double_quoted|
  begin
    string = eval( double_quoted ) # this string, as Ruby sees it
    raise unless string.is_a? String
    raise unless '"' + string + '"' == double_quoted
  rescue
    raise "Array element is not a string!"
  end
  begin  
    raise unless eval( "'#{string}'" ) == string
    "'#{string}'"
  rescue
    double_quoted
  end
}

And that SAFE level 4 is just woodoo, just an acknowledgement from me that we are doing something dangerous. I do not know to what extent it actually protects against all dangers.

In your particular case, you can create a Regexp heuristic, relying on hope that nobody will write "evil" strings in your code, such as /= *(".+") *$/ or /\\w+ *\\(* *(".+") *\\)* *$/ . That heuristic would extract some string suspects, to which you could further apply the method I wrote higher above. But I would still have human look at each replacement, and run tests on the resulting code afterwards.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM