¿Por qué String dividir con una cadena de expresiones regulares en Kotlin no es lo mismo con Java?

Tengo el siguiente código de Java:

String str = "12+20*/2-4"; List<String> arr = new ArrayList<>(); arr = str.split("\\p{Punct}"); //expected: arr = {12,20,2,4} 

Quiero el código de Kotlin equivalente, pero .split("\\p{Punct}") no funciona. No entiendo la documentation aquí: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/split.html

debe usar String#split(Regex) lugar, por ejemplo:

 val str = "12+20*/2-4"; val arr = str.split("\\p{Punct}".toRegex()); // ^--- but the result is ["12","20","","2","4"] val arr2 = arr.filter{ !it.isBlank() }; // ^--- you can filter it as further, and result is: ["12","20","2","4"] 

O puede dividir más signos de puntuación utilizando \\p{Punct}+ , por ejemplo:

 val arr = str.split("\\p{Punct}+".toRegex()) // ^--- result is: ["12","20","2","4"] 

O invierta la expresión regular y use Regex#findAll en Regex#findAll lugar, y puede averiguar los numbers negativos de esta manera. por ejemplo:

 val str ="12+20*/2+(-4)"; val arr ="(?<!\\d)-?[^\\p{Punct}]+".toRegex().findAll(str).map{ it.value }.toList() // ^--- result is ["12","20","2","-4"] // negative number is found ---^ 

Como se menciona en esta pregunta, la mayoría de los methods de manipulación de cadenas en Kotlin están sobrecargados para tomar tanto cadenas sin formatting como expresiones regulares. (Esa pregunta habla de replace pero es la misma idea para split ). Actualmente, split es tratar esa primera barra invertida como un carácter de escape en lugar de reconocerla como expresión regular.

Puede agregar una llamada toRegex() o Regex contenedor Regex dentro de su llamada para split :

 val str = "12+20*/2-4"; str.split("\\p{Punct}".toRegex()) //this str.split("Regex(\\p{Punct}")) //or this 

como se menciona en @ holi-java en su respuesta, esto coincidirá con una cadena vacía entre * y / dando ["12","20","","2","4"] . Puede usar "\\p{Punct}+" como su expresión regular para evitar esto. (Aunque tenga en count que Java da el resultado con esta cadena vacía a less que también haya un + incluido allí).

Puedes llamar

 str.split(Regex("{\\p{Punct}"))