I am getting really confused in Groovy. When to use what for Strings in Groovy ?
1) Single Quotes - ' '
2) Double Quotes - " "
3) Triple Quotes - '''
My code:
println("Tilak Rox")
println('Tilak Rox')
println('''Tilak Rox''')
All tend to produce same results.
When to Use What ?
I would confuse you even more, saying, that you can also use slash /, dolar-slash $/ and triple-double quotes """ with same result. =)
So, what's the difference:
Single vs Double quote: Most important difference. Single-quoted is ordinary Java-like string. Double-quoted is a GString, and it allows string-interpolation. I.e. you can have expressions embedded in it: println("${40 + 5}") prints 45, while println('${ 40 + 5}') will produce ${ 40 + 5}. This expression can be pretty complex, can reference variables or call methods.
Triple quote and triple double-quote is the way to make string multiline. You can open it on one line in your code, copy-paste big piece of xml, poem or sql expression in it and don't bother yourself with string concatenation.
Slashy / and dollar-slashy $/ strings are here to help with regular expressions. They have special escape rules for '\' and '/' respectfully.
As #tim pointed, there is a good official documentation for that, explaining small differences in escaping rules and containing examples as well.
Most probably you don't need to use multiline/slashy strings very often, as you use them in a very particular scenarios. But when you do they make a huge difference in readability of your code!
Single quotes ' are for basic Strings
Double quotes " are for templated Strings ie:
def a = 'tim'
assert "Hi $a" == 'Hi tim'
Triple single quotes ''' are for multi-line basic Strings
Triple double """ quotes are for multi-line templated strings
There's also slashy strings /hello $a/ which are templated
And dollar slashy Strings $/hello $a/$ which are multi-line and templated
They're all documented quite well in the documentation
Related
I am trying to include a single double quote in a string during a concatenation within JuliaLang, as below:
tmpStr = string(tmpStr, string("graph [label=\" hi \"]; "))
The output in the text file written with writedlm is:
graph [label="" hi ""]
How can I modify the string interpolation to include only a single double quote instead of this repetition?
The extra double quotes come from writedlm. writedlm uses standard CSV escaping method, which surrounds special characters with double quotes, and uses "" to represent a single double quote. This is OK, as long as you do the inverse transformation when reading the file.
A good method to trace such problems is to create a minimal working example. In this case, something like:
writedlm("tst.tst",["\""])
Which writes tst.tst, but tst.tst now has:
""""
But when read properly:
julia> data = readdlm("tst.tst")
1×1 Array{Any,2}:
"\""
As expected.
Another option to avoid getting the extra quotes is to add quotes=false as an option to writedlm, as in the following example:
julia> writedlm(STDOUT,["\""],quotes=false)
"
Let's say I make this simple string macro
macro e_str(s)
return string("I touched this: ",s)
end
If I apply it to a string with interpolation, I
obtain:
julia> e"foobar $(log(2))"
"I touched this: foobar \$(log(2))"
Whereas I would like to obtain:
julia> e"foobar $(log(2))"
"I touched this: foobar 0.6931471805599453"
What changes do I have to make to my macro declaration?
It's better to parse the string at compile-time than to delegate to Julia. Basically, put the string into an IOBuffer, scan the string for $ signs, and use the parse function whenever they come up.
macro e_str(s)
components = []
buf = IOBuffer(s)
while !eof(buf)
push!(components, rstrip(readuntil(buf, '$'), '$'))
if !eof(buf)
push!(components, parse(buf; greedy=false))
end
end
quote
string($(map(esc, components)...))
end
end
This doesn't work with escaped $ characters, but that can be resolved with some minor changes to handle \ also. I have included a basic example at the bottom of this post.
I wrote it this way because string macros are generally not for emulating Julia strings — regular macros with regular string literals are better for that purpose. So writing up the parsing yourself isn't that bad, especially because it allows customized extensions. If you really want parsing to be identical to how Julia parses it, you could escape the string and then reparse it, as #MattB suggested:
macro e_str(s)
esc(parse("\"$(escape_string(s))\""))
end
The resulting expression is a :string expression which you could dump and inspect, and then analyse the usual way.
String macros do not come with built-in interpolation facilities. However, it is possible to manually implement this functionality. Note that it is not possible to embed without escaping string literals that have the same delimiter as the surrounding string macro; that is, although """ $("x") """ is possible, " $("x") " is not. Instead, this must be escaped as " $(\"x\") ".
There are two approaches to implementing interpolation manually: implement parsing manually, or get Julia to do the parsing. The first approach is more flexible, but the second approach is easier.
Manual parsing
macro interp_str(s)
components = []
buf = IOBuffer(s)
while !eof(buf)
push!(components, rstrip(readuntil(buf, '$'), '$'))
if !eof(buf)
push!(components, parse(buf; greedy=false))
end
end
quote
string($(map(esc, components)...))
end
end
Julia parsing
macro e_str(s)
esc(parse("\"$(escape_string(s))\""))
end
This method escapes the string (but note that escape_string does not escape the $ signs) and passes it back to Julia's parser to parse. Escaping the string is necessary to ensure that " and \ do not affect the string's parsing. The resulting expression is a :string expression, which can be examined and decomposed for macro purposes.
I'm using excel's vba to match some numerical ratings. The rating can include a suffix:
+ add .25 to the rating
- subtract .25 from the rating
" add .50 to the rating
So for example if the rating: 5" would really mean 5.5 or 5+ would mean 5.25
I have a simple conditional:
if ActiveCell.Characters(i,1).Text Like [123456789+-"] then ...
Unfortunately the " produces an invalid character error. I've tried escaping as follows:
"""
'"'
\"
chr(34)
but can't seem to get the code to work. Thus, my question: How do you match a single double quote using excel VBA's Like function.
Use double quotes around Like, i.e.:
...Like "[-123456789+""]"...
Basically, when using Like, the regex is wrapped in double quotes and the double quote inside it is escaped with a second one.
Note that the - (hyphen) needs to be at the start or end of the regex, otherwise it denotes a range of characters. Thanks #ssarabando !
From help("'"):
Single and double quotes delimit character constants. They can be used
interchangeably but double quotes are preferred (and character
constants are printed using double quotes), so single quotes are
normally only used to delimit character constants containing double
quotes.
If they are interchangeable, why are double quotes preferred? I've yet to find a difference between them in my own usage. Particularly surprising is that mixed character vectors are allowable:
> c("a",'b',"c")
[1] "a" "b" "c"
Edit
I'm really asking two questions here, I guess:
Are there any situations in which ' and " behave differently?
If not, why was " chosen as the preferred version by convention?
Answers so far have been related to (2), but (1) is at least as much of-interest.
I do not know of any cases where single-quotes are different than doubles. I think the preference is due to readability and to avoid potential confusion of single quotes with back-ticks which are handled differently. It's probably very hard for the eye-brain system in the wetware to pick up a mismatched back-tick paired with a single quote.
> `newfn` <- function() {}
> newfn
function() {}
> "newfn" <- function() {}
> newfn
function() {}
> 'newfn' <- function() {}
> newfn
function() {}
> var <- c(`a`, "b", 'c')
Error: object 'a' not found
> var <- c( "b", 'c')
> var
[1] "b" "c"
> a <- 1
> identical(`a`, a)
[1] TRUE
So for assignment to names, they (s-quotes, d-quotes, and back-ticks) are all handled the same on the LHS of assignment from function, but the unquoted a and the back-ticked a are the same on the command line and are different than either of the quoted "a" or 'a'.
The other situation where there may be a difference is in data input. Persons' names may have single quotes and it not case you may want to review the handling of the two different kinds of quotes by the read.table function. By default it uses both types of quotes, but it may be necessary to "turn off" the quoting action of single quotes by setting quote="\"" so that you don't get big blobs of data turned into a single text field by mistake. The count.fields function has the same defaults as read.table, so it makes sense to do a preliminary run with this to check for shortened lines cause by mismatched single quotes:
table( count.fields('filnam.ext') )
My guess is that "single quotes" occur much more often as apostrophes, so preferring double-quotes will reduce the chance of messing things up with an apostrophe.
Concerning the first question, Are there any situations in which ' and " behave differently?, I think it is important to note that since
identical("a", 'a')
TRUE
R users (including package developers) have no way of telling the difference, hence no way of creating different behaviors for one or the other.
To avoid confusion for those who are accustomed to programming in the
C family of languages (C, C++, Java), where there is a difference in
the meaning of single quotes and double quotes.
A C programmer reads 'a' as a single character and "a" as a character
string consisting of the letter 'a' followed by a null character to
terminate the string. In R there is no character data type, there are
only character strings. For consistency with other languages it helps
if character strings are delimited by double quotes. The single quote
version in R is for convenience. On most keyboards you don't need to
use the shift key to type a single quote but you do need the shift for
a double quote.
def a = "a string"
def b = 'another'
Is there any difference? Or just like javascript to let's input ' and " easier in strings?
Single quotes are a standard java String
Double quotes are a templatable String, which will either return a GString if it is templated, or else a standard Java String. For example:
println 'hi'.class.name // prints java.lang.String
println "hi".class.name // prints java.lang.String
def a = 'Freewind'
println "hi $a" // prints "hi Freewind"
println "hi $a".class.name // prints org.codehaus.groovy.runtime.GStringImpl
If you try templating with single quoted strings, it doesn't do anything, so:
println 'hi $a' // prints "hi $a"
Also, the link given by julx in their answer is worth reading (esp. the part about GStrings not being Strings about 2/3 of the way down.
My understanding is that double-quoted string may contain embedded references to variables and other expressions. For example: "Hello $name", "Hello ${some-expression-here}". In this case a GString will be instantiated instead of a regular String. On the other hand single-quoted strings do not support this syntax and always result in a plain String. More on the topic here:
http://docs.groovy-lang.org/latest/html/documentation/index.html#all-strings
I know this is a very old question, but I wanted to add a caveat.
While it is correct that single (or triple single) quotes prevent interpolation in groovy, if you pass a shell command a single quoted string, the shell will perform parameter substitution, if the variable is an environment variable. Local variables or params will yield a bad substitution.