C# 将字符串引用替换为列表项
我一直在绞尽脑汁寻找一个“优雅”的解决方案,但我并不十分满意 可能的输入字符串:C# 将字符串引用替换为列表项,c#,string,C#,String,我一直在绞尽脑汁寻找一个“优雅”的解决方案,但我并不十分满意 可能的输入字符串: foo()条() ()条 foo ()foo()条 括号之间可以有“无限”括号和可选的非括号文本。这些空括号的内容应该按照列表条目的顺序,用取自列表的数据填充。如果没有条目或条目不足,括号将保持不变 可能的字符串替换: foo()条()替换为x,y将导致foo(x)条(y) foo()条()替换为x将导致foo(x)条() foo()条()替换为x,y,z将导致foo(x)条(y) 我希望你能明白 解决方案: 到目
foo()条()
()条
foo
()foo()条
括号之间可以有“无限”括号和可选的非括号文本。这些空括号的内容应该按照列表条目的顺序,用取自列表的数据填充。如果没有条目或条目不足,括号将保持不变
可能的字符串替换:
foo()条()
替换为x,y
将导致foo(x)条(y)
foo()条()
替换为x
将导致foo(x)条()
foo()条()
替换为x,y,z
将导致foo(x)条(y)
我希望你能明白
解决方案:
到目前为止,我的解决方案都是摆弄索引和许多特殊的逻辑来处理不同的情况
我想知道是否有一个更优雅的解决方案,例如regex。也许我现在太接近这个问题了,有一个简单的解决方案:-)
以下是一种我并不满意的方法(可读性/易懂):
var guiIdentifierIndex=0;
var guiIdentifierList=新列表{“x”、“y”、“z”、“x”、“y”};
var sourcePathItem=“foo()”;
字符串targetString=“”;
var splittedPath=sourcePathItem.Split(新字符串[]{方括号},StringSplitOptions.None);
for(int index=0;index
将替换字符串(x、y、z)拆分为逗号,然后在生成的数组中循环,用适当的值替换()的第一个匹配项
此链接显示如何替换第一个实例:StringBuilder sb=new StringBuilder();
String[]parts=sourcePathItem.Split(新字符串[]{“()”},StringSplitOptions.None);
对于(Int32 i=0;i
这个怎么样:
var template = "foo () bar ()";
var replacements = new[] {"x", "y", "z"};
var components = template.Split(new []{"()"}, StringSplitOptions.RemoveEmptyEntries);
var sb = new StringBuilder();
var replacementCount = replacements.Count();
for (int i = 0; i < components.Count(); i++)
{
var value = i >= replacementCount ? String.Empty : replacements[i];
sb.AppendFormat("{0}({1})", components[i], value);
}
var substitutedTemplate = sb.ToString();
var template=“foo()bar()”;
变量替换=新[]{“x”、“y”、“z”};
var components=template.Split(新[]{“()”},StringSplitOptions.RemoveEmptyEntries);
var sb=新的StringBuilder();
var replacementCount=replacements.Count();
对于(int i=0;i=replacementCount?字符串。空:replacements[i];
sb.AppendFormat(“{0}({1})”,组件[i],值);
}
var substitutedTemplate=sb.ToString();
您可以使用正则表达式,例如
stringsource=“foo()bar()”;
var guiIdentifierList=新列表{
“x”、“y”、“z”、“x”、“y”};
int guiIdentifierIndex=0;
//结果==“foo(x)bar(y)”
字符串结果=Regex.Replace(源,@“\(\)”,(MatchEvaluator)(
(匹配)=>”(“+(guiIdentifierIndex
var number=新列表(新[]{“1”、“2”、“3”});
字符串original=“()测试()()”;
String[]tokens=original.Split(新的[]{“()”},StringSplitOptions.None);
if(tokens.Count()>=numbers.Count())
归还原件;
返回string.Concat(tokens.Take(tokens.Count()-1)
。选择((t,i)=>t+”(“+数字[i]+”));
您可以尝试在一个foor循环中构造目标字符串,如下所示(“复制并替换”)
编辑:如果缺少右括号,则使用“向前看”不替换
var guiIdentifierIndex = 0;
var guiIdentifierList = new List<string> { "x", "y", "z" };
var sourcePathItem = "foo () bar () func()";
string targetString = "";
int srcIndex = 0;
foreach(char c in sourcePathItem)
{
targetString += c;
char lookahead = srcIndex < sourcePathItem.Length - 1 ? sourcePathItem[++srcIndex] : ' ';
if (c == '(' && lookahead == ')'
&& guiIdentifierIndex < guiIdentifierList.Count)
{
targetString += guiIdentifierList[guiIdentifierIndex++];
}
}
Console.WriteLine("Target: " + targetString);
var guiIdentifierIndex=0;
var guiIdentifierList=新列表{“x”、“y”、“z”};
var sourcePathItem=“foo()bar()func()”;
字符串targetString=“”;
int srcdex=0;
foreach(sourcePathItem中的字符c)
{
targetString+=c;
char lookahead=srcIndex
这将foo()条()
替换为x,y
到foo(x)条(y)
通常,我认为当sourcePathItem
和guidIdentifierList
越来越大时,对目标字符串使用Stringbuilder
会更好。e、 g.减少资源使用
问候我会这样做:
List<string> guiIdentifiers = new List<string>{"x", "y", "z", "x", "y"};
string input = "foo () () () () () ()";
string[] splitPath = Regex.Split(input, @"(\(\))");
for (int i = 0; i < splitPath.Length; i++)
{
if (splitPath[i] == "()" && guiIdentifiers.Count > 0)
{
splitPath[i] = string.Format("({0})", guiIdentifiers.First());
guiIdentifiers.Remove(guiIdentifiers.First());
}
}
string result = string.Join("", splitPath);
List guiIdentifiers=新列表{“x”、“y”、“z”、“x”、“y”};
字符串输入=“foo()”;
string[]splitPath=Regex.Split(输入,@“(\(\)”)”;
for(int i=0;i0)
{
splitPath[i]=string.Format(“({0})”,guiIdentifiers.First();
移除(guiIdentifiers.First());
}
}
字符串结果=string.Join(“,splitPath);
请注意,split是一个不规则动词,它的第三种形式也是split,splitted真的很奇怪,我不建议您使用。您好,您可以使用Regex-groups
下面的代码匹配(并创建一个可用于替换的正则表达式组)
var sourcePathItem = "()()foo () bar";
var q = new Queue<string>(new string[]{ "x", "y", "z", "x", "y" });
var replaced = Regex.Replace(sourcePathItem, @"\(", m =>
(m.Groups[1].Value + "(" + q.Dequeue())
);
var sourcePathItem=“()()foo()条”;
var q=新队列(新字符串[]{“x”、“y”、“z”、“x”、“y”});
var=Re
var numbers = new List<string>(new[] { "1", "2", "3" });
string original = "() test ()()";
String[] tokens = original.Split(new [] {"()"}, StringSplitOptions.None);
if (tokens.Count() >= numbers.Count())
return original;
return string.Concat(tokens.Take(tokens.Count() - 1)
.Select((t, i) => t + "(" + numbers[i] + ")"));
var guiIdentifierIndex = 0;
var guiIdentifierList = new List<string> { "x", "y", "z" };
var sourcePathItem = "foo () bar () func()";
string targetString = "";
int srcIndex = 0;
foreach(char c in sourcePathItem)
{
targetString += c;
char lookahead = srcIndex < sourcePathItem.Length - 1 ? sourcePathItem[++srcIndex] : ' ';
if (c == '(' && lookahead == ')'
&& guiIdentifierIndex < guiIdentifierList.Count)
{
targetString += guiIdentifierList[guiIdentifierIndex++];
}
}
Console.WriteLine("Target: " + targetString);
List<string> guiIdentifiers = new List<string>{"x", "y", "z", "x", "y"};
string input = "foo () () () () () ()";
string[] splitPath = Regex.Split(input, @"(\(\))");
for (int i = 0; i < splitPath.Length; i++)
{
if (splitPath[i] == "()" && guiIdentifiers.Count > 0)
{
splitPath[i] = string.Format("({0})", guiIdentifiers.First());
guiIdentifiers.Remove(guiIdentifiers.First());
}
}
string result = string.Join("", splitPath);
var sourcePathItem = "()()foo () bar";
var q = new Queue<string>(new string[]{ "x", "y", "z", "x", "y" });
var replaced = Regex.Replace(sourcePathItem, @"\(", m =>
(m.Groups[1].Value + "(" + q.Dequeue())
);