1. ホーム

[解決済み】文字列を分割しても、区切り文字を維持する方法は?

2022-04-17 20:37:46

質問

異なるデリミターで区切られた複数行の文字列があります。

(Text1)(DelimiterA)(Text2)(DelimiterC)(Text3)(DelimiterB)(Text4)

この文字列を各パーツに分割するには String.split しかし、区切り文字正規表現にマッチした実際の文字列を取得することはできないようです。

つまり、こんな感じです。

  • Text1
  • Text2
  • Text3
  • Text4

これは私が欲しいものです

  • Text1
  • DelimiterA
  • Text2
  • DelimiterC
  • Text3
  • DelimiterB
  • Text4

デリミター正規表現を使用して文字列を分割し、かつデリミターを維持するJDKの方法はありますか?

どのように解決するのですか?

正規表現の機能であるlookaheadとlookbehindを使用することができます。

System.out.println(Arrays.toString("a;b;c;d".split("(?<=;)")));
System.out.println(Arrays.toString("a;b;c;d".split("(?=;)")));
System.out.println(Arrays.toString("a;b;c;d".split("((?<=;)|(?=;))")));

そして、手に入れることができます。

[a;, b;, c;, d]
[a, ;b, ;c, ;d]
[a, ;, b, ;, c, ;, d]

最後の1つは、あなたが望むものです。

((?<=;)|(?=;)) の前に空の文字を選択することに等しい。 ; または ; .

EDITです。 Fabian Steegの可読性に関するコメントは妥当です。正規表現では常に可読性が問題になります。私が正規表現を読みやすくするためにやっていることのひとつは、変数を作って、その変数名がその正規表現が何をするのかを表すようにすることです。プレースホルダーを置くこともできます(例えば %1$s ) を使用し、Javaの String.format を使用して、プレースホルダーを実際に必要な文字列に置き換えることができます。

static public final String WITH_DELIMITER = "((?<=%1$s)|(?=%1$s))";

public void someMethod() {
    final String[] aEach = "a;b;c;d".split(String.format(WITH_DELIMITER, ";"));
    ...
}