In JavaScript, there's a regex function: RegExp test() which gets used a bit like this:
new RegExp('/regex/').test('string to match')
What this does is it tests for a match in a string. If it finds a match, it returns true, otherwise it returns false.
But I can't seem to find an equivalent on Kotlin, Android. Does anyone know if there's something like this or similar on Kotlin?
You can use the contains extension on CharSequence:
"string to match".contains(Regex("regex"))
Or the containsMatchIn method on Regex:
Regex("regex").containsMatchIn("string to match")
Related
This might be a very silly question, but I am logging the methods that are triggered in my app as strings. When an issue is submitted, I would like to automatically input the text of the strings as parameters for methods. E.g:
For method:
fun assignPot(potType: PotType, ball: DomainBall, action: PotAction) {...}
I'd like to somehow call method:
assignPot(FOUL(2, BLUE(5), SWITCH))
From String:
"FOUL(2, BLUE(5), SWITCH)"
The only workaround I can think of is to split the string and create a when -> then function to get actual classes from strings, but I wondered if there's a more concise way for this.
This is not what you want to do. You should design your app in a way that prevents users from providing input similar to actual code.
However, you can achieve this. Complex parsings like this oftenly use regex-based approaches.
As you said, you should map your string part to class. If your PotType is enum, you can do something like
val re = Regex("[^A-Za-z\s]")
val reNumbers = Regex("[^0-9\s]")
// get classes
val classNames = originalString.replace(re, "").split(" ")
// get their constructor numerical arguments
val classArgs = originalString.replace(reNumbers, "").split(" ")
After that you can implement mapping with when expression. You probably will use some collection of Any type.
As you see, this sadly leads you to parsing code by code. Concise way to solve is to implement your own script compiler/interpreter and use it in your application :) That will later lead you to dealing with security breaches and so on.
If you are logging problematic method calls and want to repeat them immediately after issue is submitted, you probably want to programatically save the calls to lambdas and call them when you receive an issue log.
In C# we have nameof() operator which return name of the class in string, what is the equivalent in Kotlin?
My use case would be something like this for
internal val TAG = nameof(MyCustomActivity)
MyCustomActivity::class.simpleName
Will output MyCustomActivity
MyCustomActivity::class.qualifiedName
Will output <your_package>.MyCustomActivity
As mentioned in the accepted answer, the <class>::class.simpleName property will provide a result similar to that of the C# nameof operator. However, unlike nameof, ::class.* cannot be evaluated at compile-time.
This is relevant, as cases where you may use the nameof operator in C#, you cannot equivalently do with ::class
For example, AspectJ's #Around annotation.
The following will fail, as you cannot interpolate non-compile-time† expressions:
#Around("#annotation(${MyAnnotation::class.simpleName})")
If Kotlin supported nameof in the same fashion as C# (where it can be used in that context) one could do this:
#Around("#annotation(${nameof(MyAnnotation)})")
So, while the accepted answer provides a functionally similar manner of resolving symbol names in Kotlin, it cannot be used with the same flexibility as nameof in C#.
† Interestingly, until writing this answer I didn't realize you can interpolate constant value (and other compile-time evaluable) expressions into annotation parameters; the following will compile:
const val FOO = "foo"
#MyAnnotation("${FOO} ${1 + 1}")
I am learning how to use the coroutines in kotlin. looking at some examples in the internet i found that within the context f the also operator the reference
it
is used. i could not find any explanation about the meaning of
it
please provide some brief explanantion about what does "it" mean
when you use the also method, it has 1 parameter.
Think of it in Java kinda like this:
foo.also(int it) {
// do stuff
}
In Kotlin, the it parameter is implicit (sometimes you might want to use it sometimes you don't).
If you want to rename it to something more readable you can
foo.also { newName ->
// do stuff with newName
}
Or just use it like it is
foo.also {
// do stuff with $it
}
So therefore when you are using a method (or a closure/lambda) if it has 1 parameter, then the implicit name of that parameter is always it.
Basically it represents the lambda parameter
let's say you want to perform anything on the variable but do to check the nullity first, you can do it like
var str:String?=null // str is of string type
now you can use it fail safe
str?.let{it:String// youll see like this
// now you can access str as **it**
}
it is the implicit name of a single parameter
For more information about it and this in scoping functions like also
Anyone wonder this ? Splitting SPACE (" ") in kotlin is not working, i tried with different regex codes but is not working at all.
Tried with this :
value.split("\\s")[0];
value.split("\\s+")[0];
value.split("\\s++")[0];
Then i came up with solution -> Create java constant class which contains this function and returns string array to your kotlin class.
Is there any other solution for this problem where we can directly achieve this thing?
Solution : As #Edson Menegatti said :
KOTLIN Specific : WORKING
values.split("\\s".toRegex())[0]
Many people suggested this solution : NOT WORKING
values.split(" ")[0]
But in my case it's not working.
Here's an issue between the Java and Kotlin implementation of String.split.
While the Java implementation does accept a regex string, the Kotlin one does not. For it to work, you need to provide an actual Regex object.
To do so, you would update your code as follows:
value.split("\\s".toRegex())[0]
Also, as #Thomas suggested, you can just use the regular space character to split your string with:
value.split(" ")[0]
Final point, if you're only using the first element of the split list, you might want to consider using first() instead of [0] - for better readability - and setting the limit parameter to 2 - for better performance.
You need to use :
.toRegex()
fun main(args: Array<String>) {
val str = "Kotlin com"
val separate1 = str.split("\\s".toRegex())[0]
println(separate1) // ------------------> Kotlin
}
OR
You can also use .split(" ")[0] to achieve result. Like
fun main(args: Array<String>) {
val str = "Kotlin com"
val separate1 = str.split(" ")[0]
println(separate1) // ----------> Kotlin
}
String#split (actually CharSequence#split) can take either a regular expression, or just a string which is interpreted literally. So:
value.split(" ")[0]
does what you want.
If you're only using the first element, it's more efficient to also pass limit = 2. Or, even better, use substringBefore.
Kotlin tries to resolve some issues that Java's String library has. For instance, Kotlin tries to be more explicit.
As a result, the split method takes a normal String and does not use it as a regex internally:
"hello world".split("\\s")[0] //no match
"hello world".split(" ")[0] // => "hello"
To explicitly use the overloaded split function that actually takes a regex, the toRegex() extension can be used (inline fun String.toRegex(): Regex (source)):
"hello world".split("\\s".toRegex())[0]// => "hello"
The following shows another example of Kotlin resolving the confusing String::replaceAll method:
Taken from a KotlinConf presentation of Svetlana Isakova, co-author of “Kotlin in Action”
Single delimiter
val splittedStringList = "123.345-80A".split(".")
println(splittedStringList[0])
Several delimiters
println("123.345-80A".split(".", "-"))
Using regex
println("123.345-80A".split("\\.|-".toRegex()))
Try Kotlin Online
Simply use value.split("\s".toRegex())
1.Splits and iterates all items
value.split("\\s".toRegex()).forEach { item ->
//use item
}
2.Spits and use first item
value.split("\\s".toRegex()).first()
3.Spits and use last item
value.split("\\s".toRegex()).last()
I'm trying to do something like:
val barcodes = arrayOf("123", "456", "789")
realm.where(Product::class.java).in("barcode", barcodes).findAll()
However "in" is a Kotlin function and I can't access the in(String filedName, String[] values) method of RealmQuery object.
Currently I have a java class that does the job and returns the result, but I was wondering is there a more graceful workaround for this?
As stated in the Escaping for Java identifiers that are keywords in Kotlin:
Some of the Kotlin keywords are valid identifiers in Java: in, object,
is, etc. If a Java library uses a Kotlin keyword for a method, you can
still call the method escaping it with the backtick (`) character
For example:
realm.where(Product::class.java).`in`("barcode", barcodes).findAll()