为什么使用正则表达式字符串的 Kotlin String.split 与 Java 不同?

2022-09-01 23:02:44

我有以下Java代码:

String str = "12+20*/2-4";
List<String> arr = new ArrayList<>();

arr = str.split("\\p{Punct}");

//expected: arr = {12,20,2,4}

我想要等效的 Kotlin 代码,但不起作用。我不明白这里的文档:https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/split.html.split("\\p{Punct}")


答案 1

您应该改用,例如: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"]

OR反转正则表达式并改用,您可以通过这种方式找到负数。例如: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   ---^

答案 2

对于正则表达式行为,您的参数必须是 类型 ,而不仅仅是包含特殊正则表达式字符。RegexString

Kotlin 中的大多数字符串操作方法(替换拆分等)都可以同时采用和参数,但是如果您想要特定于正则表达式的匹配,则必须将其转换为。StringRegexStringRegex

可以使用 以下方法完成此转换:String.toRegex()Regex(String)

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

当前 split 将第一个反斜杠视为转义字符,而不是将其识别为特殊的正则表达式序列。


正如@holi-java在他们的答案中提到的,这将匹配和给予之间的空字符串。您可以用作正则表达式来避免这种情况。(但请注意,Java使用这个空字符串给出输出,除非那里也包含a。*/["12","20","","2","4"]"\\p{Punct}+"+