почему разделение строки с помощью строки регулярного выражения в Kotlin не совпадает с Java?
у меня есть следующий код Java:
String str = "12+20*/2-4";
List<String> arr = new ArrayList<>();
arr = str.split("p{Punct}");
//expected: arr = {12,20,2,4}
Я хочу эквивалентный код Котлина, но .split("p{Punct}") не работает. Я не понимаю документацию здесь:https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/split.html
3 ответов
вы должны использовать String#split(Regex) вместо этого, например:
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"]
или вы можете разделить более пунктуацияС помощью \p{Punct}+ , например:
val arr = str.split("\p{Punct}+".toRegex())
// ^--- result is: ["12","20","2","4"]
или инверсия regex и с помощью Regex#findAll вместо этого, и вы можете узнать отрицательные числа таким образом. например:
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 ---^
как уже упоминалось в этом вопросе большинство методов обработки строк в Kotlin перегружены, чтобы взять как необработанные строки, так и регулярное выражение. (Что вопросы говорит о replace но это та же самая идея для split). В настоящее время split рассматривает эту первую обратную косую черту как escape-символ, а не распознает ее как регулярное выражение.
вы можете добавить toRegex() звонок или Regex обертка внутри вашего вызова split:
val str = "12+20*/2-4";
str.split("\p{Punct}".toRegex()) //this
str.split("Regex(\p{Punct}")) //or this
как упоминалось @holi-java в ответ это будет соответствовать пустой строке между * и / дав ["12","20","","2","4"]. Вы можете использовать "\p{Punct}+" как ваше регулярное выражение, чтобы избежать этого. (Хотя, обратите внимание, что Java дает выход С эта пустая строка, если только + включается там же.)