Java - 按数字和字母拆分字符串
Java - Split String by Number and Letters
所以我有,例如,这样的字符串 C3H20IO
我想做的是拆分这个字符串,所以我得到以下内容:
Array1 = {C,H,I,O}
Array2 = {3,20,1,1}
1
作为 Array2
的第三个元素表示 I
元素的单原子性质。 O
也一样。这实际上是我正在努力的部分。
这是一个化学方程式,所以我需要根据元素的名称和原子数量等来分离元素
您可以使用两种模式:
- [0-9]
- [a-zA-Z]
被他们各自分裂两次
List<String> letters = Arrays.asList(test.split("[0-9]"));
List<String> numbers = Arrays.asList(test.split("[a-zA-Z]"))
.stream()
.filter(s -> !s.equals(""))
.collect(Collectors.toList());
if(letters.size() != numbers.size()){
numbers.add("1");
}
您可以使用 (?<=\D)(?=\d) 等正则表达式拆分字符串。试试这个:
String alphanum= "abcd1234";
String[] part = alphanum.split("(?<=\D)(?=\d)");
System.out.println(part[0]);
System.out.println(part[1]);
会输出
abcd
1234
使用输入长度的大小制作(for 循环)并添加以下条件
if(i==number)
// add it to the number array
if(i==character)
//add it into character array
我建议使用零宽度先行正则表达式按大写字母拆分(以提取 C12
、O2
、Si
等项目),然后将每个项目拆分为元素及其数字体重:
List<String> elements = new ArrayList<>();
List<Integer> weights = new ArrayList<>();
String[] items = "C6H12Si6OH".split("(?=[A-Z])"); // [C6, H12, Si6, O, H]
for (String item : items) {
String[] pair = item.split("(?=[0-9])", 2); // e.g. H12 => [H, 12], O => [O]
elements.add(pair[0]);
weights.add(pair.length > 1 ? Integer.parseInt(pair[1]) : 1);
}
System.out.println(elements); // [C, H, Si, O, H]
System.out.println(weights); // [6, 12, 6, 1, 1]
这在假设每个元素都以大写字母开头的情况下有效,即如果你有 "Fe",你不会在字符串中将其表示为 "FE"。基本上,您将字符串拆分为每个大写字母,然后按字母和数字拆分每个新字符串,如果新拆分不包含数字,则添加“1”。
String s = "C3H20IO";
List<String> letters = new ArrayList<>();
List<String> numbers = new ArrayList<>();
String[] arr = s.split("(?=\p{Upper})"); // [C3, H20, I, O]
for (String str : arr) { //[C, 3]:[H, 20]:[I]:[O]
String[] temp = str.split("(?=\d)", 2);
letters.add(temp[0]);
if (temp.length == 1) {
numbers.add("1");
} else {
numbers.add(temp[1]);
}
}
System.out.println(Arrays.asList(letters)); //[[C, H, I, O]]
System.out.println(Arrays.asList(numbers)); //[[3, 20, 1, 1]]
我是这样操作的
ArrayList<Integer> integerCharacters = new ArrayList();
ArrayList<String> stringCharacters = new ArrayList<>();
String value = "C3H20IO"; //Your value
String[] strSplitted = value.split("(?<=\D)(?=\d)|(?<=\d)(?=\D)"); //Split numeric and strings
for(int i=0; i<strSplitted.length; i++){
if (Character.isLetter(strSplitted[i].charAt(0))){
stringCharacters.add(strSplitted[i]); //If string then add to strings array
}
else{
integerCharacters.add(Integer.parseInt(strSplitted[i])); //else add to integer array
}
}
您可以试试这个方法:
String formula = "C3H20IO";
//insert "1" in atom-atom boundry
formula = formula.replaceAll("(?<=[A-Z])(?=[A-Z])|(?<=[a-z])(?=[A-Z])|(?<=\D)$", "1");
//split at letter-digit or digit-letter boundry
String regex = "(?<=\D)(?=\d)|(?<=\d)(?=\D)";
String[] atoms = formula.split(regex);
输出:
atoms: [C, 3, H, 20, I, 1, O, 1]
现在所有偶数索引(0、2、4...)都是原子,奇数是相关数字:
String[] a = new String[ atoms.length/2 ];
int[] n = new int[ atoms.length/2 ];
for(int i = 0 ; i < a.length ; i++) {
a[i] = atoms[i*2];
n[i] = Integer.parseInt(atoms[i*2+1]);
}
输出:
a: [C, H, I, O]
n: [3, 20, 1, 1]
这样好吗? (不使用 split
)
String line = "C3H20ZnO2ABCD";
String pattern = "([A-Z][a-z]*)(((?=[A-Z][a-z]*|$))|\d+)";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(line);
while (m.find( )) {
System.out.print(m.group(1));
if (m.group(2).length() == 0) {
System.out.println(" 1");
} else {
System.out.println(" " + m.group(2));
}
}
您可以使用正则表达式通过 Matcher.find() 方法滑过您的输入。
这是一个大概的例子:
String input = "C3H20IO";
List<String> array1 = new ArrayList<String>();
List<Integer> array2 = new ArrayList<Integer>();
Pattern pattern = Pattern.compile("([A-Z][a-z]*)([0-9]*)");
Matcher matcher = pattern.matcher(input);
while(matcher.find()){
array1.add(matcher.group(1));
String atomAmount = matcher.group(2);
int atomAmountInt = 1;
if((atomAmount != null) && (!atomAmount.isEmpty())){
atomAmountInt = Integer.valueOf(atomAmount);
}
array2.add(atomAmountInt);
}
我知道,缺少从 List 到 Array 的转换,但它应该能让您了解如何解决您的问题。
没有REGEX
的方法和使用ArrayList
存储的数据:
String s = "C3H20IO";
char Chem = '-';
String val = "";
boolean isFisrt = true;
List<Character> chemList = new ArrayList<Character>();
List<Integer> weightList = new ArrayList<Integer>();
for (char c : s.toCharArray()) {
if (Character.isLetter(c)) {
if (!isFisrt) {
chemList.add(Chem);
weightList.add(Integer.valueOf(val.equals("") ? "1" : val));
val = "";
}
Chem = c;
} else if (Character.isDigit(c)) {
val += c;
}
isFisrt = false;
}
chemList.add(Chem);
weightList.add(Integer.valueOf(val.equals("") ? "1" : val));
System.out.println(chemList);
System.out.println(weightList);
输出:
[C, H, I, O]
[3, 20, 1, 1]
所以我有,例如,这样的字符串 C3H20IO
我想做的是拆分这个字符串,所以我得到以下内容:
Array1 = {C,H,I,O}
Array2 = {3,20,1,1}
1
作为 Array2
的第三个元素表示 I
元素的单原子性质。 O
也一样。这实际上是我正在努力的部分。
这是一个化学方程式,所以我需要根据元素的名称和原子数量等来分离元素
您可以使用两种模式:
- [0-9]
- [a-zA-Z]
被他们各自分裂两次
List<String> letters = Arrays.asList(test.split("[0-9]"));
List<String> numbers = Arrays.asList(test.split("[a-zA-Z]"))
.stream()
.filter(s -> !s.equals(""))
.collect(Collectors.toList());
if(letters.size() != numbers.size()){
numbers.add("1");
}
您可以使用 (?<=\D)(?=\d) 等正则表达式拆分字符串。试试这个:
String alphanum= "abcd1234";
String[] part = alphanum.split("(?<=\D)(?=\d)");
System.out.println(part[0]);
System.out.println(part[1]);
会输出
abcd 1234
使用输入长度的大小制作(for 循环)并添加以下条件
if(i==number)
// add it to the number array
if(i==character)
//add it into character array
我建议使用零宽度先行正则表达式按大写字母拆分(以提取 C12
、O2
、Si
等项目),然后将每个项目拆分为元素及其数字体重:
List<String> elements = new ArrayList<>();
List<Integer> weights = new ArrayList<>();
String[] items = "C6H12Si6OH".split("(?=[A-Z])"); // [C6, H12, Si6, O, H]
for (String item : items) {
String[] pair = item.split("(?=[0-9])", 2); // e.g. H12 => [H, 12], O => [O]
elements.add(pair[0]);
weights.add(pair.length > 1 ? Integer.parseInt(pair[1]) : 1);
}
System.out.println(elements); // [C, H, Si, O, H]
System.out.println(weights); // [6, 12, 6, 1, 1]
这在假设每个元素都以大写字母开头的情况下有效,即如果你有 "Fe",你不会在字符串中将其表示为 "FE"。基本上,您将字符串拆分为每个大写字母,然后按字母和数字拆分每个新字符串,如果新拆分不包含数字,则添加“1”。
String s = "C3H20IO";
List<String> letters = new ArrayList<>();
List<String> numbers = new ArrayList<>();
String[] arr = s.split("(?=\p{Upper})"); // [C3, H20, I, O]
for (String str : arr) { //[C, 3]:[H, 20]:[I]:[O]
String[] temp = str.split("(?=\d)", 2);
letters.add(temp[0]);
if (temp.length == 1) {
numbers.add("1");
} else {
numbers.add(temp[1]);
}
}
System.out.println(Arrays.asList(letters)); //[[C, H, I, O]]
System.out.println(Arrays.asList(numbers)); //[[3, 20, 1, 1]]
我是这样操作的
ArrayList<Integer> integerCharacters = new ArrayList();
ArrayList<String> stringCharacters = new ArrayList<>();
String value = "C3H20IO"; //Your value
String[] strSplitted = value.split("(?<=\D)(?=\d)|(?<=\d)(?=\D)"); //Split numeric and strings
for(int i=0; i<strSplitted.length; i++){
if (Character.isLetter(strSplitted[i].charAt(0))){
stringCharacters.add(strSplitted[i]); //If string then add to strings array
}
else{
integerCharacters.add(Integer.parseInt(strSplitted[i])); //else add to integer array
}
}
您可以试试这个方法:
String formula = "C3H20IO";
//insert "1" in atom-atom boundry
formula = formula.replaceAll("(?<=[A-Z])(?=[A-Z])|(?<=[a-z])(?=[A-Z])|(?<=\D)$", "1");
//split at letter-digit or digit-letter boundry
String regex = "(?<=\D)(?=\d)|(?<=\d)(?=\D)";
String[] atoms = formula.split(regex);
输出:
atoms: [C, 3, H, 20, I, 1, O, 1]
现在所有偶数索引(0、2、4...)都是原子,奇数是相关数字:
String[] a = new String[ atoms.length/2 ];
int[] n = new int[ atoms.length/2 ];
for(int i = 0 ; i < a.length ; i++) {
a[i] = atoms[i*2];
n[i] = Integer.parseInt(atoms[i*2+1]);
}
输出:
a: [C, H, I, O]
n: [3, 20, 1, 1]
这样好吗? (不使用 split
)
String line = "C3H20ZnO2ABCD";
String pattern = "([A-Z][a-z]*)(((?=[A-Z][a-z]*|$))|\d+)";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(line);
while (m.find( )) {
System.out.print(m.group(1));
if (m.group(2).length() == 0) {
System.out.println(" 1");
} else {
System.out.println(" " + m.group(2));
}
}
您可以使用正则表达式通过 Matcher.find() 方法滑过您的输入。
这是一个大概的例子:
String input = "C3H20IO";
List<String> array1 = new ArrayList<String>();
List<Integer> array2 = new ArrayList<Integer>();
Pattern pattern = Pattern.compile("([A-Z][a-z]*)([0-9]*)");
Matcher matcher = pattern.matcher(input);
while(matcher.find()){
array1.add(matcher.group(1));
String atomAmount = matcher.group(2);
int atomAmountInt = 1;
if((atomAmount != null) && (!atomAmount.isEmpty())){
atomAmountInt = Integer.valueOf(atomAmount);
}
array2.add(atomAmountInt);
}
我知道,缺少从 List 到 Array 的转换,但它应该能让您了解如何解决您的问题。
没有REGEX
的方法和使用ArrayList
存储的数据:
String s = "C3H20IO";
char Chem = '-';
String val = "";
boolean isFisrt = true;
List<Character> chemList = new ArrayList<Character>();
List<Integer> weightList = new ArrayList<Integer>();
for (char c : s.toCharArray()) {
if (Character.isLetter(c)) {
if (!isFisrt) {
chemList.add(Chem);
weightList.add(Integer.valueOf(val.equals("") ? "1" : val));
val = "";
}
Chem = c;
} else if (Character.isDigit(c)) {
val += c;
}
isFisrt = false;
}
chemList.add(Chem);
weightList.add(Integer.valueOf(val.equals("") ? "1" : val));
System.out.println(chemList);
System.out.println(weightList);
输出:
[C, H, I, O]
[3, 20, 1, 1]