c# - 用字符串括号内的分号替换逗号的最佳方法
问题描述
给定以下字符串:
string foo = "Foo, Bar, Baz (A, B, C), Fiz, Bang (Fiz, Bang)";
我想把它改成
Foo, Bar, Baz (A; B; C), Fiz, Bang (Fiz; Bang)
或者,如果我能以某种方式在 List 中以下列方式将其转换为字符串数组:
Foo
Bar
Baz (A, B, C)
Fiz
Bang (Fiz, Bang)
现在我正在做一个非常讨厌的方法,它有一个自定义的 foreach 并且感觉不干净或可扩展。当有更好的方法时,我觉得我正在努力做到这一点。
所以我呼吁hivemind寻求更好的解决方案。
编辑:
public static void StuntForEachNext<T>(this IList<T> collection, Action<T, T, bool> func)
{
for (int i = 0; i < collection.Count - 1; i++)
{
func(collection[i], collection[i + 1], i == collection.Count - 2);
}
}
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;
}
}
这段代码将不得不重新编写,因为我被告知括号中的内容可能比简单的昏迷更复杂,所以我决定暂时将它们存储在一个字符串中。
但是,我认为我可能会吸引更多的人,因为否则我只会做 ax += ", " 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();
}
然后
string result = Transform(foo);
推荐阅读
- mysql - Mysql:如何使用组创建高性能视图
- javascript - 如何处理不同reducer的状态以触发react redux中的通知
- r - R中多个因素的汇总统计?
- c - 拼字游戏 cs50 计算分数
- rust - 无法使用 FLTK (Rust) 构建项目
- download - 如何更改量角器中的下载路径/位置
- firebase - 在 firebase auth 中使用电话和电子邮件进行验证
- java - spring注入构造函数时,如何知道并注入参数是否为列表对象?
- python - Matplotlib 到 TikZ ridgeplot 问题(出现轴)
- python-3.x - 图像直方图转化为线形的算法