C#如果字符串为',则替换该字符串;s不在{大括号}内

C#如果字符串为',则替换该字符串;s不在{大括号}内,c#,regex,string,C#,Regex,String,由于不幸的过去选择,我有一个如下格式字符串: # {0}mm {1}mm x {2}mm 它分两个阶段处理,第一个阶段是将#字符替换为带simple的字符串 formatString = formatString.Replace("#", "foo") 不知何故,原始字符串更改为在格式字符串中包含OctorOpes,如下所示: # {0}mm {1:0.##}mm x {2:0.##}mm 因为我仍然需要用foo替换第一个,但是string.replace(“#“,“foo”)将替换所有出

由于不幸的过去选择,我有一个如下格式字符串:

# {0}mm {1}mm x {2}mm
它分两个阶段处理,第一个阶段是将
#
字符替换为带simple的字符串

formatString = formatString.Replace("#", "foo")
不知何故,原始字符串更改为在格式字符串中包含OctorOpes,如下所示:

# {0}mm {1:0.##}mm x {2:0.##}mm
因为我仍然需要用
foo
替换第一个
,但是
string.replace(“#“,“foo”)
将替换所有出现的
,结果是
foo{0}mm{1:0foo}mm x{2:0.foo}mm


这就是为什么我只想在不在花括号内的情况下替换
符号。我认为它可以通过正则表达式实现,但我没有想到正确的表达式。

您的正则表达式可以像
^(#)一样简单。
^字符串的开头,(#)出现一次

如果你真的不太懂正则表达式,我绝对可以推荐你
这是一个非常直观的正则表达式生成器

您的正则表达式可以简单到
^(#)
^字符串的开头,(#)一次出现#

如果你真的不太懂正则表达式,我绝对可以推荐你 这是一个非常直观的正则表达式生成器

这应该可以:

(?<!{[^{}]*)(?![^{}]*})#
(?
仅在以下情况下匹配:

  • 它前面没有开口大括号,后面没有其他大括号
  • 它后面没有右大括号,前面没有其他大括号
  • 这是一个杂烩
  • 前两个确保您不在一对大括号内,但不在一对大括号与另一对大括号之间匹配

    但是,如果您希望匹配的哈希仅在开始时出现,则是一种更好的方法。

    这应该可以:

    (?<!{[^{}]*)(?![^{}]*})#
    
    (?
    仅在以下情况下匹配:

  • 它前面没有开口大括号,后面没有其他大括号
  • 它后面没有右大括号,前面没有其他大括号
  • 这是一个杂烩
  • 前两个确保您不在一对大括号内,但不在一对大括号与另一对大括号之间匹配


    但是,如果您希望匹配的哈希仅出现在开始时,则是一种更好的方法。

    使用Regex.Replace代替String.Replace

    样品

    using System.Text.RegularExpressions;
    namespace TestReplaceFirst
    {
        class Program
        {
            static void Main(string[] args)
            {
            var source = new List<string> { "# {0}mm {1}mm x {2}mm", "# {0}mm {1:0.##}mm x {2:0.##}mm", "{0}mm {1}mm x {2}mm # #", "{0}mm # {1:0.##}mm x {2:0.##}mm" };
    
            string pattern = "(?<!{[^{}]*)(?![^{}]*})#";
            string replacement = "foo";
            Regex rgx = new Regex(pattern);
    
            foreach (var str in source)
            {
                string result = rgx.Replace(str, replacement);
                Console.WriteLine("Original String:    '{0}'", str);
                Console.WriteLine("Replacement String: '{0}'", result);
            }
            Console.ReadKey();       
        }
    }
    

    使用Regex.Replace代替String.Replace

    样品

    using System.Text.RegularExpressions;
    namespace TestReplaceFirst
    {
        class Program
        {
            static void Main(string[] args)
            {
            var source = new List<string> { "# {0}mm {1}mm x {2}mm", "# {0}mm {1:0.##}mm x {2:0.##}mm", "{0}mm {1}mm x {2}mm # #", "{0}mm # {1:0.##}mm x {2:0.##}mm" };
    
            string pattern = "(?<!{[^{}]*)(?![^{}]*})#";
            string replacement = "foo";
            Regex rgx = new Regex(pattern);
    
            foreach (var str in source)
            {
                string result = rgx.Replace(str, replacement);
                Console.WriteLine("Original String:    '{0}'", str);
                Console.WriteLine("Replacement String: '{0}'", result);
            }
            Console.ReadKey();       
        }
    }
    

    我知道你已经有了一个被接受的答案,但这个问题碰巧也有一个非常普遍和漂亮的解决方案,所以为了完成,这里是。这个情况与这个问题非常相似

    我们可以用一个非常简单的正则表达式来解决这个问题:

    {[^}]*}|(#+)
    
    交替的左侧与complete
    {curlies}
    匹配。我们将忽略这些匹配。右侧匹配并捕获哈希值
    #
    到组1,我们知道它们是正确的,因为它们没有与左侧的表达式匹配

    此程序显示了如何使用正则表达式(请参见列表底部的结果):

    参考


    我知道你已经有了一个公认的答案,但这个问题碰巧也有一个非常笼统和漂亮的解决方案,所以为了完成这个问题,这里就是。这种情况与这个问题非常相似

    我们可以用一个非常简单的正则表达式来解决这个问题:

    {[^}]*}|(#+)
    
    交替的左侧与complete
    {curlies}
    匹配。我们将忽略这些匹配。右侧匹配并捕获哈希值
    #
    到组1,我们知道它们是正确的,因为它们没有与左侧的表达式匹配

    此程序显示了如何使用正则表达式(请参见列表底部的结果):

    参考


    为什么不在应用格式后替换“#”呢?因为更改系统的处理太难了order@AlessandroD“安德里亚另一个原因——在一般情况下——是您需要避免替换从替换值引入的任何散列。@Richard说得很好,但我的想法是逐渐颠倒操作,或者像您的回答一样,使用我一直觉得很难使用的正则表达式。为什么不在应用格式后替换“#”呢?因为更改系统的处理太难了order@AlessandroD安德里亚:另一个原因——在一般情况下——是您需要避免替换从替换值引入的任何散列@Richard说得很好,但我的想法逐渐颠倒了操作顺序,或者像你的回答一样,使用我一直觉得很难使用的正则表达式,但是我的单曲<代码>
    可能不会出现在字符串的开头,那么你肯定应该使用Richard的解决方案。但是我的单曲<代码>
    可能不会出现在字符串的开头stringThen你肯定应该使用Richard的解决方案。表达式的哪一部分说“它没有被遵循”?@Axarydax the
    (?!…)
    是a。表达式的哪一部分说“它没有被遵循”?@Axarydax the
    (?!…)
    是a。我确实考虑过这种方法(当我的前两个前瞻性测试失败时:-)这无疑增加了复杂性。虽然回调委托(或者更惯用的是lambda)的使用功能强大,但要复杂得多;而且,在这种情况下,感觉是错误的(IMHO),因为回调实际上只是为了做一些可以在正则表达式本身中完成的额外模式匹配(将问题分为两个工具).PS.如果缩进,代码会更清晰(不需要难看的“结束”注释)。@Richard当您说lambda进行更多模式匹配时…
    if(m.Groups[1].Value!=“”)
    并不是我所说的模式匹配!哈哈……我同意你的观点,它有优点也有缺点。这种方法的一个巨大好处是,如果下周二我们决定在任何
    中也排除散列,那么它的实现和维护都非常容易!(只需在ex左侧添加另一个选项
    ]*>|