Escape triple quote within kotlin raw string - string

I'm trying to create a raw string that contains three quotes in itself.
The resulting string x should contain something like """abc""".
I've been able to create the string with the following code, but was wondering if there's a simpler solution for this.
val x = """${'"'.toString().repeat(3)}abc${'"'.toString().repeat(3)}"""

There's no easy way to use a triple quote directly in a string literal.
One workaround I've sometimes used is to make an interim variable to hold the triple-quote string.
val quotes = "\"\"\""
val result = "${quotes}abc${quotes}"

I think a simpler way would be to escape them manually, so like:
val x = "\"\"\"abc\"\"\""

Related

Kotlin String.split, ignore when delimiter is inside a quote

I have a string:
Hi there, "Bananas are, by nature, evil.", Hey there.
I want to split the string with commas as the delimiter. How do I get the .split method to ignore the comma inside the quotes, so that it returns 3 strings and not 5.
You can use regex in split method
According to this answer the following regex only matches , outside of the " mark
,(?=(?:[^\"]\"[^\"]\")[^\"]$)
so try this code:
str.split(",(?=(?:[^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*\$)".toRegex())
You can use split overload that accepts regular expressions for that:
val text = """Hi there, "Bananas are, by nature, evil.", Hey there."""
val matchCommaNotInQuotes = Regex("""\,(?=([^"]*"[^"]*")*[^"]*$)""")
println(text.split(matchCommaNotInQuotes))
Would print:
[Hi there, "Bananas are, by nature, evil.", Hey there.]
Consider reading this answer on how the regular expression works in this case.
You have to use a regular expression capable of handling quoted values. See Java: splitting a comma-separated string but ignoring commas in quotes and C#, regular expressions : how to parse comma-separated values, where some values might be quoted strings themselves containing commas
The following code shows a very simple version of such a regular expression.
fun main(args: Array<String>) {
"Hi there, \"Bananas are, by nature, evil.\", Hey there."
.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)".toRegex())
.forEach { println("> $it") }
}
outputs
> Hi there
> "Bananas are, by nature, evil."
> Hey there.
Be aware of the regex backtracking problem: https://www.regular-expressions.info/catastrophic.html. You might be better off writing a parser.
If you don't want regular expressions:
val s = "Hi there, \"Bananas are, by nature, evil.\", Hey there."
val hold = s.substringAfter("\"").substringBefore("\"")
val temp = s.split("\"")
val splitted: MutableList<String> = (temp[0] + "\"" + temp[2]).split(",").toMutableList()
splitted[1] = "\"" + hold + "\""
splitted is the List you want

Getting substrings from a string in c# in the format Domain\Alias

I have a variable which has strings stored in the format "domain\alias" and I want to split this in two different strings domain and alias.
I have two solutions for the above case, but none of them are working in my case.
solution 1: separating alias from the string.
for this I am using the code below:
int index = name.IndexOf("\") + 1;
string piece = name.Substring(index);
where name is the variable which stores the string in the format "domain\alias"
This solution doesn't work for '\' however it works in case of '.'
solution 2:
separating domain from the string.
Here I got a solution below:
var domainFormattedString = #"fareast\v-sidmis";
var parts = domainFormattedString.Split('\\');
var domainString = parts[0];
return domainString;
this works, but it needs a string prefixed with #symbol and i have my string stored in the variable name for which this solution doesn't work.
Someone please help me to extract the two substrings from my variable name.
EDIT 1: Thanks all for your help! I figured out the issue...when i explicitly declare a string as: var x = "domian\alias" it creates and issue as \ is treated as a escape character by c# so i had to append # at the beginning. But I got to know that when a string is read from a user, the solution works!
\ has a special meaning so you need to override the escape sequence to be treated as normal character with another escape character.
string input = #"domain\alias";
int inputindex= input.IndexOf("\\");
string domain = input.Substring(0, inputindex);
string alias = input.Substring(inputindex+1);
Hope It helps eventhough better late than never :)

In Swift how to obtain the "invisible" escape characters in a string variable into another variable

In Swift I can create a String variable such as this:
let s = "Hello\nMy name is Jack!"
And if I use s, the output will be:
Hello
My name is Jack!
(because the \n is a linefeed)
But what if I want to programmatically obtain the raw characters in the s variable? As in if I want to actually do something like:
let sRaw = s.raw
I made the .raw up, but something like this. So that the literal value of sRaw would be:
Hello\nMy name is Jack!
and it would literally print the string, complete with literal "\n"
Thank you!
The newline is the "raw character" contained in the string.
How exactly you formed the string (in this case from a string literal with an escape sequence in source code) is not retained (it is only available in the source code, but not preserved in the resulting program). It would look exactly the same if you read it from a file, a database, the concatenation of multiple literals, a multi-line literal, a numeric escape sequence, etc.
If you want to print newline as \n you have to convert it back (by doing text replacement) -- but again, you don't know if the string was really created from such a literal.
You can do this with escaped characters such as \n:
let secondaryString = "really"
let s = "Hello\nMy name is \(secondaryString) Jack!"
let find = Character("\n")
let r = String(s.characters.split(find).joinWithSeparator(["\\","n"]))
print(r) // -> "Hello\nMy name is really Jack!"
However, once the string s is generated the \(secondaryString) has already been interpolated to "really" and there is no trace of it other than the replaced word. I suppose if you already know the interpolated string you could search for it and replace it with "\\(secondaryString)" to get the result you want. Otherwise it's gone.

Templates escaping in Kotlin multiline strings

If I want to use $ sign in multiline strings, how do I escape it?
val condition = """ ... $eq ... """
$eq is parsed as a reference to a variable. How to escape $, so that it will not be recognized as reference to variable? (Kotlin M13)
From the documentation
A raw string is delimited by a triple quote ("""), contains no
escaping and can contain newlines and any other character
You would need to use a standard string with newlines
" ...\n \$eq \n ... "
or you could use the literal representation
""" ... ${'$'}eq ... "
Funny, but that works:
val eq = "\$eq"
print("""... $eq ..."""") // just like you asked :D
Actually, if eq is a number (a price, or sth), then you probably want to calculate it separately, and an additional external calculation as I suggested won't hurt.
In the case where you know ahead of time what $-variables you want (like when querying Mongo, as it looks like you might be doing), you can create a little helper object that defines those variables. You also get some protection against accidentally misspelling one of your operators, which is neat.
object MongoString {
inline operator fun invoke(callback: MongoString.() -> String) = callback()
val eq = "\$eq"
val lt = "\$lt"
// ... and all the other operators ...
}
fun test() {
val query = MongoString { """{"foo": {$lt: 10}}""" }
}
I wrote simple versions for update and query strings for mongo here: https://gist.github.com/Yona-Appletree/29be816ca74a0d93cdf9e6f5e23dda15

groovy replace double quotes with single and single with double

I have a string "['type':'MultiPolygon', 'coordinates':[[73.31, 37.46], [74.92, 37.24]]]"
How can I replace all single quotes with double quotes and double to with single?
The result should be like this:
'["type":"MultiPolygon", "coordinates":[[73.31, 37.46], [74.92, 37.24]]]'
From link given by #yate, you can find a method:
tr(String sourceSet, String replacementSet)
and apply that to your string as:
def yourString = ...
def changedString = yourString.tr(/"'/,/'"/)
that will do the job.
You want to use the replaceAll method. Since the first conversion will be overridden by the second, you may need a temporary variable:
String replacePlaceholder = '%%%' // Some unlikely-to-occur value
yourString = yourString.replaceAll('\'', replacePlaceholder)
.replaceAll('"', '\'')
.replaceAll(replacePlaceholder, '"')
It's certainly not the most efficient way to do it, but it's a start.

Resources