使用C#从字符串中的[]括号中删除逗号

4
我想在方括号[]之间删除逗号,而不是从字符串中删除整个逗号。
这是我的字符串,
string result= "a,b,c,[c,d,e],f,g,[h,i,j]";
期望的输出为:
a,b,c,[cde],f,g,[hij]
提前感谢。

3
你需要的是一个简单的状态机...它可以有两种状态:在括号内或括号外...从那里开始就很简单了。 - xanatos
@Corak 为什么不直接把那个作为答案发布呢? - juharr
你需要处理嵌套的括号吗? - juharr
@Corak 如果您不确定它是否正确,那为什么要发帖呢?顺便说一句,这是正确的。 - juharr
3个回答

4

正如我所写,你需要一个简单的状态机(在括号内和括号外)......然后对于每个字符,你分析它并且如果必要的话改变状态机的状态,并决定是否需要输出它。

public static string RemoveCommas(string str) 
{
    int bracketLevel = 0;

    var sb = new StringBuilder(str.Length);

    foreach (char ch in str) 
    {
        switch (ch) {
            case '[':
                bracketLevel++;
                sb.Append(ch);
                break;

            case ']':
                if (bracketLevel > 0) {
                    bracketLevel--;
                }

                sb.Append(ch);
                break;

            case ',':
                if (bracketLevel == 0) {
                    sb.Append(ch);
                }

                break;

            default:
                sb.Append(ch);
                break;
        }
    }

    return sb.ToString();
}

使用方法如下:

string result = "a,b,c,[c,d,e],f,g,[h,i,j]";
Console.WriteLine(RemoveCommas(result));

请注意,为了“保存”状态机的状态,我使用一个int,以便它与递归括号一起工作,例如a,b,[c,d,[e,f]g,h]i,j
作为一个有趣的练习,可以使用较慢的LINQ表达式完成此操作:
string result2 = result.Aggregate(new 
{
    BracketLevel = 0,
    Result = string.Empty,
}, (state, ch) => new {
    BracketLevel = ch == '[' ? 
        state.BracketLevel + 1 : 
            ch == ']' && state.BracketLevel > 0 ? 
                state.BracketLevel - 1 : 
                state.BracketLevel,
    Result = ch != ',' || state.BracketLevel == 0 ? state.Result + ch : state.Result
}).Result;

最终,代码非常相似...有一个状态(BracketLevel)和正在构建的字符串(Result)一起传递。请不要使用,它只是作为一个有趣的LINQ片段编写的。

2

正则表达式方法

string stringValue = "a,b,c,[c,d,e],f,g,[h,i,j]";
var result = Regex.Replace(stringValue, @",(?![^\]]*(?:\[|$))", string.Empty);

如果您没有嵌套的括号。

谢谢。找到一个真正有效的正则表达式花了一些时间。我不得不针对我的情况调整尖括号:@",(?![^>]*(?:<|$))" - Smörgåsbord

0
你可以尝试这个:
var output = new string(result
                         .Where((s, index) => s != ',' ||
                                              IsOutside(result.Substring(0, index)))
                         .ToArray()
                       );

//output: a,b,c,[cde],f,g,[hij]

然而

private static bool IsOutside(string value)
{
     return value.Count(i => i == '[') <= value.Count(i => i == ']');
}

但请记住,这不是完成此工作的有效方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接