为什么带有正则表达式字符串的Kotlin String.split与Java不一样?

Ily*_*eev 11 java regex split kotlin

我有以下Java代码:

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

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

//expected: arr = {12,20,2,4}
Run Code Online (Sandbox Code Playgroud)

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

hol*_*ava 13

你应该使用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"]
Run Code Online (Sandbox Code Playgroud)

或者您可以拆分多标点符号的使用S \\p{Punct}+,例如:

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

或者 反转正则表达式并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   ---^
Run Code Online (Sandbox Code Playgroud)


Riv*_*ver 5

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

Kotlin 中的大多数字符串操作方法(replacesplit等)都可以使用StringRegex参数,但是如果您想要特定StringRegex正则表达式的匹配,则必须将其转换为。

可以使用String.toRegex()或完成此转换Regex(String)

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

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


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