替换字符串中的一个字符而不是两个字符

时间:2015-10-07 07:49:28

标签: c# regex

我想用C#替换字符串中单个出现但不是两个字符。

例如,我想用空字符串替换&,但是当事件为&&时不能。另一个示例,a&b&&c在替换后将变为ab&&c

如果我使用&[^&]之类的正则表达式,它也会匹配&之后的字符,而我又不想替换它。

我发现的另一个解决方案是迭代字符串字符。

你知道一个更清洁的解决方案吗?

6 个答案:

答案 0 :(得分:5)

您可以匹配&&&(或任意数量的重复),只能用空字符串替换单个字符串:

str = Regex.Replace(str, "&+", m => m.Value.Length == 1 ? "" : m.Value);

答案 1 :(得分:2)

要仅匹配一个&&之前或之后),请使用环顾四周 (?<!&)(?!&)

(?<!&)&(?!&)

请参阅regex demo

您尝试使用仍然匹配字符的否定字符类,并且您需要使用前瞻/后视来检查某些字符缺席/存在,而不使用它

请参阅regular-expressions.info

  

如果你想要匹配其他东西不匹配的东西,那么否定的先行是必不可少的。在解释character classes时,本教程解释了为什么您不能使用否定字符类来匹配q后跟u。否定前瞻提供了解决方案:q(?!u)

     

Lookbehind具有相同的效果,但向后工作。它告诉正则表达式引擎暂时在字符串中向后退一步,以检查lookbehind内的文本是否可以在那里匹配。 (?<!a)b匹配"b"之前没有"a"的{​​{1}},使用负面后瞻。它与cab不匹配,但与床上或债务中的b(以及仅b)匹配。

答案 2 :(得分:1)

您可以使用此正则表达式:@"(?<!&)&(?!&)"

var str = Regex.Replace("a&b&&c", @"(?<!&)&(?!&)", "");
Console.WriteLine(str);   // ab&&c

答案 3 :(得分:0)

你可以这样做:

public static string replacement(string oldString, char charToRemove)
{
    string newString = "";
    bool found = false;
    foreach (char c in oldString)
    {
        if (c == charToRemove && !found)
        {
            found = true;
            continue;
        }
        newString += c;
    }
    return newString;
}

尽可能通用

答案 4 :(得分:0)

我会使用这样的东西,IMO应该比使用Regex更好:

public static class StringExtensions
{
    public static string ReplaceFirst(this string source, char oldChar, char newChar)
    {
        if (string.IsNullOrEmpty(source)) return source;
        int index = source.IndexOf(oldChar);
        if (index < 0) return source;
        var chars = source.ToCharArray();
        chars[index] = newChar;
        return new string(chars);
    }
}

答案 5 :(得分:0)

我将从评论中为此声明做出贡献:

  

在这种情况下,只有奇数个&#39;&amp;&#39;的子串。将被所有&#34;&amp;&#34;除了最后一个&#34;&amp;&#34; 。 &#34;&安培;&安培;&安培;&#34;将是&#34;&amp;&amp;&#34;和&#34;&amp;&amp;&amp;&amp;&#34;将是&#34;&amp;&amp;&amp;&amp;&#34;

这是一个使用balancing groups的非常简洁的解决方案(虽然我不会把它称为特别干净也不容易阅读)。

<强>代码:

string str = "11&222&&333&&&44444&&&&55&&&&&";
str = Regex.Replace(str, "&((?:(?<2>&)(?<-2>&)?)*)", "$1$2");

<强>输出:

11222&&333&&44444&&&&55&&&&

ideone demo

  1. 它始终与第一个&匹配(未捕获)。
  2. 如果它后跟偶数&,则它们会匹配并存储在$1中。第二组被第一组捕获,但随后被第二组减去。
  3. 但是,如果有&的奇数,则可选组(?<-2>&)?不匹配,并且该组不会被减去。然后,$2将捕获额外的&
  4. 例如,匹配主题"&&&&",第一个字符将被消耗,并且不会被捕获( 1 )。第二个和第三个字符匹配,但$2被减去( 2 )。对于最后一个字符,会捕获$2 3 )。最后3个字符存储在$1中,&中还有$2个字样。
    然后,替换"$1$2" == "&&&&"