处理字符串问题的一些通用方法
例如处理化学分子式
输入的为Fe2(SO4)3 输出的结果是2个Fe,3个S,12个O
H2SO4 2个H,1个H,4个O
using System;
using UnityEngine;
using System.Collections.Generic;
public static class StrHelper
{
// 返回字符串中存在的指定字符的全部索引
public static int[] CharIndex(string str, string _char)
{
int index = 0;
List<int> list = new List<int>();
while ((index = str.IndexOf(_char, index)) != -1)
{
list.Add(index);
index = index + _char.Length;
}
return list.ToArray();
}
// 从一个字符串,获取指定两个不同字符,中间的字符串方法
public static string[] MidString(string str, string start, string end, bool self = false)
{
int[] sIndex = CharIndex(str, start);
int[] eIndex = CharIndex(str, end);
//LogArr(eIndex);
List<string> list = new List<string>();
for (int i = 0; i < sIndex.Length; i++)
{
int a, b;
if (self)
{
a = sIndex[i];
b = eIndex[i] - a + start.Length;
}
else
{
a = sIndex[i] + start.Length;
b = eIndex[i] - a;
}
string temp = str.Substring(a, b);
list.Add(temp);
//Debug.Log(temp);
}
return list.ToArray();
}
// 计算字符串中元素的个数
public static Dictionary<string, int> EleCalculCount(string[] all, string[] eleStr, int[] multNums)
{
Dictionary<string, int> eleDict = new Dictionary<string, int>();
foreach (string ele in all) eleDict.Add(ele, 0);
for (int i = 0; i < eleStr.Length; i++)
{
string eleSegment = eleStr[i]; // 一段元素字条串
// 每种元素的情况
for (int k = 0; k < all.Length; k++)
{
string ele = all[k];
int[] eleIndex = StrHelper.CharIndex(eleSegment, ele);
if (eleIndex.Length > 0)
{
int[] nums = StrHelper.StrBehindNums(eleSegment, ele);
foreach (int num in nums)
{
if (num == 0) eleDict[ele] += 1 * (multNums[i] == 0 ? 1 : multNums[i]);
else eleDict[ele] += num * (multNums[i] == 0 ? 1 : multNums[i]);
}
}
}
}
return eleDict;
}
// 返回指定字符后面的数字
public static int[] StrBehindNums(string str, string ele)
{
int[] eIndex = StrHelper.CharIndex(str, ele);
//Debug.Log($"---------{ele}:");
//LogArr(eIndex);
List<int> nums = new List<int>();
foreach (int index in eIndex)
{
int num = StrHelper.GetBehandNumber(str, ele, index);
nums.Add(num);
}
return nums.ToArray();
}
// 找出指定字符串后面的数字
public static int GetBehandNumber(string str, string ele, int index)
{
int num = 0;
int a = index + ele.Length;
// 元素在最后面
if (a == str.Length)
{
return num;
}
string temp = str.Substring(a);
// 拼合是数字的char
string n = "";
foreach (char c in temp)
{
if (!char.IsNumber(c)) break;
else
{
n += c.ToString();
}
}
if (n == "") return num;
// Debug.Log($"c:{temp}----{n}");
num = int.Parse(n);
return num;
}
// 打印数组中的元素
public static void LogArr(Array arr)
{
foreach (var a in arr)
{
Debug.Log(a.ToString());
}
}
// 字符串是不是数字
public static bool StrIsNumber(string str)
{
bool isNum = true;
foreach (char a in str)
{
if (!char.IsNumber(a)) isNum = false;
}
return isNum;
}
}
// 处理括号中的元素的情况
string[] mults = StrHelper.MidString(str,"(",")");
int[] multNums = StrHelper.StrBehindNums(str,")");
Dictionary<string,int> eleDict = StrHelper.EleCalculCount(all,mults,multNums);
// 移除括号内容+后面的数字
string tempStr = str;
string[] sMutles = StrHelper.MidString(str,"(",")",true);
for(int i=0;i<sMutles.Length;i++){
string sMutlePlus = sMutles[i] + multNums[i];
tempStr = tempStr.Replace(sMutlePlus,"");
}
// 处理括号外的元素的情况
string[] eles = {tempStr};
int[] elesNums = {0};
Dictionary<string,int> eleDict2 = StrHelper.EleCalculCount(all,eles,elesNums);
// 汇总计算元素个数
foreach(KeyValuePair<string, int> kvp in eleDict2){
eleDict[kvp.Key] += kvp.Value;
}
// 输出结果
Debug.Log($"str:{str}");
foreach(string ele in all){
Debug.Log($"{ele}的个数是:{eleDict[ele]}");
}