How do I replace multiple characters in a String? - kotlin

How do I replace multiple characters in a String?
Like Java's replaceAll(regex:replacement:) function.
str.replaceAll("[$,.]", "") //java code
This answer is very close but I want to change more than one character at the same time.

[$,.] is regex, which is the expected input for Java's replaceAll() method. Kotlin, however, has a class called Regex, and string.replace() is overloaded to take either a String or a Regex argument.
So you have to call .toRegex() explicitly, otherwise it thinks you want to replace the String literal [$,.]. It's also worth mentioning that $ in Kotlin is used with String templates, meaning in regular strings you have to escape it using a backslash. Kotlin supports raw Strings (marked by three " instead of one) which don't need to have these escaped, meaning you can do this:
str = str.replace("""[$,.]""".toRegex(), "")
In general, you need a Regex object. Aside using toRegex() (which may or may not be syntactical sugar), you can also create a Regex object by using the constructor for the class:
str = str.replace(Regex("""[$,.]"""), "")
Both these signal that your string is regex, and makes sure the right replace() is used.

If you're happy to work with regular expressions, then refer to the accepted answer here. If you're curious as to how you can achieve this without regular expressions, continue reading.
You can use the String.filterNot(predicate:) and Set.contains(element:) functions to define a String.removeAll extension function as follows:
/**
* #param charactersToRemove The characters to remove from the receiving String.
* #return A copy of the receiving String with the characters in `charactersToRemove` removed.
*/
fun String.removeAll(charactersToRemove: Set<Char>): String {
return filterNot { charactersToRemove.contains(it) }
}
You would call on this function as follows: myString.removeAll(setOf('$', '.'))

Related

WebStorm Live Template, separate a string of inputs

I want to create a Live Template for createSelector:
export const someSelector = createSelector(getThis, getThat, getSomethingElse, (this, that, somethingElse) =>
$END$
)
I can get it to work pretty well with a single argument (e.g., only getThis which then results in (this) in the arrow function args).
// template text
createSelector($someSelector$, ($variable$) => $END$)
// variables
// expression for "variable":
decapitalize(regularExpression(someSelector, "get", ""))
This works correctly with a single argument as mentioned above, and almost works correctly with multiple arguments, except for the capitalization:
createSelector(getThis, getThat, getSomethingElse, (this, That, SomethingElse) => /* $end$ */)
I tried wrapping that whole thing in camelCase but then of course the commas and spaces are gone.
The issue is clearly that I'm processing the whole string at once so the whole string is run through whatever string formatting function. There doesn't appear to be any way to treat individual instances of "get" separately.
I tried capture groups which I really thought would work:
decapitalize(regularExpression(someSelector, "get(\w+)", "$1"))
But that doesn't replace anything, it just copies the whole thing:
createSelector(getThis, getThat, (getThis, getThat) => )
Is there any way to accomplish this?
UPDATE:
I even learned Groovy script and wrote the following, which works in a groovy playground, but gets in WebStorm gets the same result as my final example above!
groovyScript("return _1.replaceAll(/get(\w+)/) { it[1].uncapitalize() };", someSelector)
This could be done with RegEx .. but Java does not seem to support \l replacement modifier (to be used as \l$1 instead of $1 in your initial regularExpression() code).
Live example (works in PCRE2, e.g. in PHP): https://regex101.com/r/6faVqC/1
Docs on replacement modifiers: https://www.regular-expressions.info/refreplacecase.html
In any case: this whole thing is handled by Java and you are passing RegEx pattern or GrovyScript code inside double quotes. Therefore any \ symbols would need to be escaped.
You need to replace get(\w+) by get(\\w+).
The following seems to work just fine for me here (where someSelector is the Live Template variable):
groovyScript("return _1.replaceAll(/get(\\w+)/) { it[1].uncapitalize() };", someSelector)

Difference between replaceCharacterInRange and stringByReplacingOccurrenceOfString

I m very confused with the string replacing methods of objective c.
Please tell where to use ReplaceCharacterInRange method and Where to use
stringByReplacingOccurrenceOfString Method.
These two methods differ a lot.
replaceStringWithCharactersInRange: withString:replaces all characters in the given range with the new string. It works on a NSMutableString and changes the string object you call it on.
In contrast stringByReplacingOccurrencesOfString:withString: replaces all occurrences of a given string, but returns a new string object. So it does work with immutable string as well.
So you use the first method if you want to keep your string but change parts of it while you use the second when you want to replace certain substrings within the string without changing the original string.

How to construct a Complex from a String using Python's C-API?

How to use the Python C-API for the Complex class (documented here) to:
convert a general PyObject (which might be a String, Long, Float, Complex) into a Complex PyObject?
convert a Complex PyObject into String PyObject?
Python has a complex() function, documented here):
Return a complex number with the value real + imag*j or convert a
string or number to a complex number. If the first parameter is a
string, it will be interpreted as a complex number and the function
must be called without a second parameter. The second parameter can
never be a string. Each argument may be any numeric type (including
complex). If imag is omitted, it defaults to zero and the function
serves as a numeric conversion function like int(), long() and
float(). If both arguments are omitted, returns 0j.
However, it isn't obvious which API function (if any) is backing it.
It would appear none of them, is the above paragraph talks about two PyObject* parameters, and none of the API functions listed match that signature.
When in doubt, do what Python does: call the constructor.
PyObject *c1 = PyObject_CallFunction(PyComplex_Type, "s", "1+2j");
If (!c1)
return NULL;

Exclamation operator?

I'm learning D and have seen a lot of code like this:
ushort x = to!ushort(args[1]);
I assume this casts args[1] to ushort, but what's the difference between this and cast(ushort)?
EDIT: And what other uses does the exclamation mark operator have?
In D,
to!ushort(args[1])
is shorthand for the template instantiation
to!(ushort)(args[1])
and is similar to
to<ushort>(args[1])
in languages like C++/Java/C#.
The exclamation point is to note the fact that it's not a regular argument, but a template argument.
The notation does not use angle brackets because those are ridiculously difficult to parse correctly for a compiler (they make the grammar very context-sensitive), which makes it that much more difficult to implement a correct compiler. See here for more info.
The only other use I know about is just the unary 'not' operation (e.g. false == !true)... I can't think of any other uses at the moment.
Regarding the cast:
cast(ushort) is an unchecked cast, so it won't throw an exception if the value is out of range.
to!ushort() is a checked cast, so it throws an exception if the value is out of range.
The exclamation mark here is not an operator, it is just a token part of the explicit template instantiation syntax (described in detail here).
std.conv.to (docs) is a function template for converting between arbitrary types. It is implemented entirely in the library and has no special support in the language. It has a broader and different scope compared to the cast operator.
The to template takes two type parameters; a "to" type and a "from" type, in that order. In your example, the template is explicitly instantiated with the single type argument ushort for the "to" parameter, and a second type argument string (assuming args comes from the first parameter to main) is automatically inferred from the regular function argument passed to the function (args[1]) as the "from" parameter.
The resulting function takes a string parameter and returns a ushort parsed from that string, or throws an exception if it failed. The cast operator will not attempt this kind of high-level conversion.
Note that if there is more than one explicit template parameter, or that parameter has more than one token in it (ushort is a single keyword token), you must wrap the template parameter list in parentheses:
ushort result;
result = to!(typeof(result))(args[1]);
In this example, typeof, (, result and ) are four separate tokens and the parentheses are thus required.
To answer your last question, the ! token is also used for the unary not operator, unrelated to template instantiations:
bool yes = true;
bool no = !yes; // 'no' is false
You already got two excellent answers by jA_cOp and Merhdad. I just want answer directly to the OP question (what's the difference between this and cast(ushort)?) - The difference is that cast(ushort)args[1] will not work (you cannot cast from a string to an uint just like that), while the to!(type)(param) template knows what to do with the string and how to convert it to the primitive type.

Escape dot from GString

I would like to learn how to escape dot in GString so groovy (1.8) does not treat it as a part of an variable inside sql.execute. I have the following code:
Map<String, String> dbSettings = [schemaName:"testSchema"];
String myDbPrefix = dbSetting.schemaName + ".";
sql.execute "DELETE FROM ${myDbPrefix}myTable"
And I got this error:
Ignoring groovy.lang.MissingPropertyException: No such property: myTable for class: java.lang.String
Clearly indicating that . was interpreted as part of variable ${myDbPrefix}.
Does escaping the embedded variable help?
  sql.execute "DELETE FROM ${Sql.expand myDbPrefix}myTable"
I got hit by this problem today. GStrings get handled by a special way in GroovySQL. It's mentioned in the javadoc. It does automatic parameter binding.
Each value in the GString will become a parameter (?) which gets set as a JDBC prepared statement parameter.
What a surprise!
I'm going to fix the problem in my application by subclassing the Sql class and overriding the GString handling with plain ".toString()" .
Documented in Groovy wiki:
GString Use Cases - GSQL Another use case for GString is GSQL where
parameters can be passed into SQL statements using this same mechanism
which makes for a neat way to integrate Groovy with other languages
like SQL. GroovySql then converts the expressions to ? and uses a JDBC
PreparedStatement and passes the values in, preserving their types.
If you explicitly want to coerce the GString to a String you can use
the toString() method. Groovy can also automatically coerce GStrings
into Strings for you.