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