web-dev-qa-db-ja.com

正規表現文字列を含むKotlin String.splitがJavaと同じではないのはなぜですか?

次のJavaコードがあります:

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

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

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

同等のKotlinコードが必要ですが、.split("\\p{Punct}")が機能しません。私はここのドキュメントを理解していません: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/split.html

12
Ilya Fedoseev

代わりに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"]

[〜#〜] or [〜#〜]\\p{Punct}+を使用すると、さらに多くのPunctuationを分割できます例えば:

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

[〜#〜] or [〜#〜]invert正規表現を使用し、代わりに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   ---^
12
holi-java

正規表現の動作の場合、引数mustは、特殊な正規表現文字を含む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

現在 split は、最初のバックスラッシュを特別な正規表現シーケンスとして認識するのではなく、エスケープ文字として扱っています。


@ -holi-Javaの their answer で言及されているように、これは*/の間の空の文字列に一致し、["12","20","","2","4"]を与えます。これを回避するには、正規表現として"\\p{Punct}+"を使用できます。 (ただし、Javaは、+もそこに含まれていない限り、この空の文字列withで出力を提供します)。

2
River

電話できます

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