简体   繁体   English

C#替换字符串(如果不在{大括号中)

[英]C# replace string if it's not within {braces}

Due to an unfortunate past choice I have a following format string that looks like this: 由于过去的不幸选择,我有一个如下所示的格式字符串:

# {0}mm {1}mm x {2}mm

It's processed in two stages, first one was to replace # character with a string with simple 它分为两个阶段进行处理,第一个阶段是将#字符替换为简单的字符串

formatString = formatString.Replace("#", "foo")

Somehow the original string changed to include octothorpes inside the format string as: 原始字符串以某种方式更改为在格式字符串中包括八叉索,如下所示:

# {0}mm {1:0.##}mm x {2:0.##}mm

Because I still have to replace the first one # with foo , but the string.Replace("#","foo") will replace all occurences of # , resulting in foo {0}mm {1:0foofoo}mm x {2:0.foofoo}mm" 因为我仍然必须用foo替换第一个# ,但是string.Replace("#","foo")将替换#所有出现,从而导致foo {0}mm {1:0foofoo}mm x {2:0.foofoo}mm"

That's why I'd like to replace # symbol only if it's not inside curly braces. 这就是为什么我只在大括号内不替换#符号的原因。 I think it can be achieved by a regex, but the correct expression doesn't come to my mind. 我认为可以通过正则表达式来实现,但是我不知道正确的表达方式。

This should work: 这应该工作:

(?<!{[^{}]*)(?![^{}]*})#

Which will only match if: 仅在以下情况下才匹配

  1. It is not preceded by an opening brace not followed by other braces, 它前面没有开括号,后面没有其他括号,
  2. It is not followed by a closing brace not preceded by other braces, 它后面不能紧跟一个大括号,而不是其他大括号,
  3. It is a hash. 这是一个哈希。

The first two ensure you are not inside a brace pair, but not matching from one pair of braces to the other. 前两个确保您不在一对大括号内,但不能从一对大括号匹配另一对大括号。

However if the hash you wish to match only occurs at the start then AlexInTime's solution is a much better approach. 但是,如果您希望匹配的哈希值仅在开始时出现,那么AlexInTime的解决方案是更好的方法。

I know you already have an accepted answer, but this question also happens to have a solution that is quite general and beautiful, so for completion, here it is. 我知道您已经有了一个可以接受的答案,但是这个问题也碰巧有一个非常通用和美观的解决方案,因此,为了完成,就在这里。 This situation is very similar to this question to "regex-match a pattern, excluding..." 这种情况与“正则表达式匹配模式,不包括...”的问题非常相似

We can solve it with a beautifully-simple regex: 我们可以使用一个非常简单的正则表达式来解决它:

{[^}]*}|(#+)

The left side of the alternation | 交替的左侧| matches complete {curlies} . 匹配完整的{curlies} We will ignore these matches. 我们将忽略这些匹配。 The right side matches and captures hashes # to Group 1, and we know they are the right ones because they were not matched by the expression on the left. 右侧将哈希#匹配并捕获到第1组,我们知道它们是正确的,因为左侧的表达式未匹配它们。

This program shows how to use the regex (see the results at the bottom of the online demo ): 该程序显示了如何使用正则表达式(请参见在线演示底部的结果):

using System;
using System.Text.RegularExpressions;
using System.Collections.Specialized;
class Program
{
static void Main() {
var myRegex = new Regex(@"{[^}]*}|(#+)");
string s1 = @"# {0}mm ####{1:0.##}mm ##x {2:0.##}mm";

string replaced = myRegex.Replace(s1, delegate(Match m) {
if (m.Groups[1].Value != "") return "";
else return m.Value;
});
Console.WriteLine("\n" + "*** Replacements ***");
Console.WriteLine(replaced);


Console.WriteLine("\nPress Any Key to Exit.");
Console.ReadKey();

} // END Main
} // END Program

Reference 参考

your regex can be as simple as ^(#) ^ start of string, (#) one occurence of # 您的正则表达式可以很简单,例如^(#) ^字符串的开头,(#)出现#

if you don't really know regex to much I can definitely recommed http://txt2re.com/ which is a VERY visual regex builder 如果您真的不太了解正则表达式,我绝对可以推荐给http://txt2re.com/ ,这是一个非常直观的正则表达式生成器

Use the Regex.Replace in stead of String.Replace 使用Regex.Replace代替String.Replace

See http://msdn.microsoft.com/en-us/library/haekbhys(v=vs.110).aspx 参见http://msdn.microsoft.com/zh-cn/library/haekbhys(v=vs.110).aspx

Sample 样品

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

Output: 输出:

Original String:    '# {0}mm {1}mm x {2}mm'
Replacement String: 'foo {0}mm {1}mm x {2}mm'
Original String:    '# {0}mm {1:0.##}mm x {2:0.##}mm'
Replacement String: 'foo {0}mm {1:0.##}mm x {2:0.##}mm'
Original String:    '{0}mm {1}mm x {2}mm # #'
Replacement String: '{0}mm {1}mm x {2}mm foo #'
Original String:    '{0}mm # {1:0.##}mm x {2:0.##}mm'
Replacement String: '{0}mm foo {1:0.##}mm x {2:0.##}mm'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM