почему разделение строки с помощью строки регулярного выражения в 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 дает выход С эта пустая строка, если только + включается там же.)


можно назвать

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