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())
        );