C# 用字符串括号内的分号替换逗号的最佳方法
给定以下字符串:C# 用字符串括号内的分号替换逗号的最佳方法,c#,.net-core-3.1,C#,.net Core 3.1,给定以下字符串: string foo = "Foo, Bar, Baz (A, B, C), Fiz, Bang (Fiz, Bang)"; 我想把它改成 Foo, Bar, Baz (A; B; C), Fiz, Bang (Fiz; Bang) 或者,如果我能以某种方式在列表中以以下方式将其转换为字符串数组: Foo Bar Baz (A, B, C) Fiz Bang (Fiz, Bang) 现在我正在做一个非常讨厌的方法,它有一个定制的foreach,感觉不干净或者不可伸缩。当
string foo = "Foo, Bar, Baz (A, B, C), Fiz, Bang (Fiz, Bang)";
我想把它改成
Foo, Bar, Baz (A; B; C), Fiz, Bang (Fiz; Bang)
或者,如果我能以某种方式在列表中以以下方式将其转换为字符串数组:
Foo
Bar
Baz (A, B, C)
Fiz
Bang (Fiz, Bang)
现在我正在做一个非常讨厌的方法,它有一个定制的foreach,感觉不干净或者不可伸缩。当有更好的方法的时候,我觉得我做这件事很难
因此,我呼吁蜂群思维寻求更好的解决方案
编辑:
public static void StuntForEachNext(此IList集合,Action func)
{
for(int i=0;i
解析内部类特技
{
公共字符串名称{get;set;}
公共int StuntCount{get;set;}
公共列表已分配_关联_特技{get;set;}=new List();
公共重写字符串ToString()
{
返回$“Stunt:{MainStuntName}x{StuntCount}({Assigned_Associated_Stunts.Count})”;
}
公共静态列表解析特技(字符串特技)
{
List returnStunts=新列表();
bool-isInParen=false;
Stunt_Parsed newStunt=新的Stunt_Parsed();
特技。拆分(',')。特技foreachnext((特技,下一个特技,下一个特技)=>
{
字符串解析_stunt=stunt;
if(stunt.Contains('('))
{
isInParen=true;
//把这个和下一个结合起来
字符串关联特技=特技+“,”+下一个特技;
//解析括号内的内容
int p1=assoc_stunt.IndexOf('(');//16
int p2=相关特技长度;
如果(关联特技包含('))
{
p2=联合特技表演指数(');
isInParen=false;
}
字符串s2=assoc_特技。子字符串(p1+1,p2-p1-1);/“光环盾,动态盾,myfoo
string assoc_stunt1=string.Empty;
string assoc_stunt2=string.Empty;
foreach(s2.Split(',')中的字符串x)
{
字符串newString=x.Trim();
newStunt.Assigned_Associated_stunt.Add(newString);
}
parsed_stunt=(parsed_stunt.Substring(0,parsed_stunt.Length-(parsed_stunt.Length-parsed_stunt.IndexOf('('))).Trim();//拼写焦点x2
}
else if(nextStunt.Contains('))| | isInParen)
{
//已解析
//什么也不做。
字符串newString=nextStunt.Replace(“,”,”).Replace(“),”).Trim();
newStunt.Assigned_Associated_stunt.Add(newString);
if(nextStunt.Contains('))
{
returnStunts.Add(newStunt);
isInParen=false;
newStunt=解析的新特技();
}
返回;
}
else如果(stunt.Contains('))
{
返回;
}
parsed_stunt=parsed_stunt.Trim();
if(解析的_stunt.ToLower()包含(“x”))
{
int lastX=parsed_stunt.ToLower().LastIndexOf(“x”);
newStunt.StuntCount=int.Parse(解析的stunt.Substring(lastX+1,解析的stunt.Length-lastX-1));
newStunt.MainStuntName=parsed_stunt.Substring(0,lastX-1);
}
其他的
{
newStunt.StuntCount=1;
newStunt.MainStuntName=parsed_stunt;
}
如果(!isInParen)
{
returnStunts.Add(newStunt);
newStunt=解析的新特技();
}
});
回归特技;
}
}
这段代码将不得不重新编写,因为我被告知括号中的内容可能比简单的coma更复杂,所以我决定暂时将它们存储在一个字符串中
然而,我认为我可能会吸引更多的人,因为否则我只需做一个x+=”,“nextStunt;
,直到闭括号中的你可以尝试使用有限状态机(FSM);它有foreach
循环,我希望它是简单的,而不是丑陋的:
private static string Transform(string value) {
if (string.IsNullOrEmpty(value))
return value;
StringBuilder sb = new StringBuilder(value.Length);
int count = 0;
foreach (char c in value)
if (c == ',')
sb.Append(count > 0 ? ';' : c);
else {
sb.Append(c);
if (c == '(')
count += 1;
else if (c == ')')
count -= 1;
}
return sb.ToString();
}
然后
您可以使用
Regex
。但是,请共享您当前的代码。您应该使用Regex
查看此问题/答案绝对是最好的方法谢谢,我将查看Regex-way.Regex.Replace(输入,@“(?>[^()]|(?)(|)(?)*((c)(!)”,m=>m.Value.Replace(“,”,“,”,“;”)这是斯诺塔姆芬的回答。谢谢大家,我来结束这个问题。你太棒了!
internal class Stunt_Parsed
{
public string MainStuntName { get; set; }
public int StuntCount { get; set; }
public List<string> Assigned_Associated_Stunts { get; set; } = new List<string>();
public override string ToString()
{
return $"Stunt: {MainStuntName} x{StuntCount} ({Assigned_Associated_Stunts.Count})";
}
public static List<Stunt_Parsed> ParseStunts(string stunts)
{
List<Stunt_Parsed> returnStunts = new List<Stunt_Parsed>();
bool isInParen = false;
Stunt_Parsed newStunt = new Stunt_Parsed();
stunts.Split(',').StuntForEachNext((stunt, nextStunt, isNextLast) =>
{
string parsed_stunt = stunt;
if (stunt.Contains('('))
{
isInParen = true;
// Combine this one and the next one
string assoc_stunt = stunt + "," + nextStunt;
// Parse the things inside of the parentheses
int p1 = assoc_stunt.IndexOf('('); // 16
int p2 = assoc_stunt.Length;
if (assoc_stunt.Contains(')'))
{
p2 = assoc_stunt.IndexOf(')');
isInParen = false;
}
string s2 = assoc_stunt.Substring(p1 + 1, p2 - p1 - 1); // "Aura shield, dynamic shield, myfoo
string assoc_stunt1 = string.Empty;
string assoc_stunt2 = string.Empty;
foreach (string x in s2.Split(','))
{
string newString = x.Trim();
newStunt.Assigned_Associated_Stunts.Add(newString);
}
parsed_stunt = (parsed_stunt.Substring(0, parsed_stunt.Length - (parsed_stunt.Length - parsed_stunt.IndexOf('(')))).Trim(); // Spell Focus x2
}
else if (nextStunt.Contains(')') || isInParen)
{
// Already parsed
// Do nothing.
string newString = nextStunt.Replace(",", "").Replace(")", "").Trim();
newStunt.Assigned_Associated_Stunts.Add(newString);
if (nextStunt.Contains(')'))
{
returnStunts.Add(newStunt);
isInParen = false;
newStunt = new Stunt_Parsed();
}
return;
}
else if (stunt.Contains(')'))
{
return;
}
parsed_stunt = parsed_stunt.Trim();
if (parsed_stunt.ToLower().Contains(" x"))
{
int lastX = parsed_stunt.ToLower().LastIndexOf("x");
newStunt.StuntCount = int.Parse(parsed_stunt.Substring(lastX + 1, parsed_stunt.Length - lastX - 1));
newStunt.MainStuntName = parsed_stunt.Substring(0, lastX - 1);
}
else
{
newStunt.StuntCount = 1;
newStunt.MainStuntName = parsed_stunt;
}
if (!isInParen)
{
returnStunts.Add(newStunt);
newStunt = new Stunt_Parsed();
}
});
return returnStunts;
}
}
private static string Transform(string value) {
if (string.IsNullOrEmpty(value))
return value;
StringBuilder sb = new StringBuilder(value.Length);
int count = 0;
foreach (char c in value)
if (c == ',')
sb.Append(count > 0 ? ';' : c);
else {
sb.Append(c);
if (c == '(')
count += 1;
else if (c == ')')
count -= 1;
}
return sb.ToString();
}
string result = Transform(foo);