ルックアラウンドを使用して実行できます。
String[] parts = input.split("(?<=.)(?=[A-Z])");
ルックアラウンドは、ゼロ幅の消費しないアサーションです。
この正規表現は、2 つのルック アラウンドが一致する場所で入力を分割します。
(?<=.)
「前の文字がある」ことを意味します(つまり、入力の開始時ではありません)
(?=[A-Z])
「次の文字は大文字」を意味します (すべての要素は で始まりますA-Z
)
これは、いくつかのエッジケースの二重文字記号を含むテストです。
public static void main(String[] args) {
String input = "C9KrBr2H11NO2";
String[] parts = input.split("(?<=.)(?=[A-Z])");
System.out.println(Arrays.toString(parts));
}
出力:
[C9, Kr, Br2, H11, N, O2]
その後、個々のコンポーネントを分割したい場合は、次のネストされた呼び出しを使用しますsplit()
。
public static void main(String[] args) {
String input = "C9KrBr2H11NO2";
for (String component : input.split("(?<=.)(?=[A-Z])")) {
// split on non-digit/digit boundary
String[] symbolAndNumber = component.split("(?<!\\d)(?=\\d)");
String element = symbolAndNumber[0];
// elements without numbers won't be split
String count = symbolAndNumber.length == 1 ? "1" : symbolAndNumber[1];
System.out.println(element + " x " + count);
}
}
出力:
C x 9
Kr x 1
Br x 2
H x 11
N x 1
O x 2