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

本文关键字:两个 字符 字符串 替换 一个 | 更新日期: 2023-09-27 18:16:39

我想用c#替换字符串中出现的单个字符,而不是两个字符。

例如,我想用空字符串替换&,但当出现&&时不替换。又如,a&b&&c替换后会变成ab&&c

如果我使用像&[^&]这样的正则表达式,它也将匹配&之后的字符,我不想替换它。

我找到的另一个解决方案是遍历字符串字符。

你知道一个更干净的解决方案吗?

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

如果只匹配一个&(前面或后面没有&),请使用查找 (?<!&)(?!&):

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

参见regex demo

您尝试使用一个仍然匹配字符的否定字符类,并且您需要使用向前看/向后看来检查一些字符的缺失/存在,而不消耗它。

看到regular-expressions.info:

如果你想匹配某个内容而不是后面跟着其他内容,那么负向前看是必不可少的。在解释字符类时,本教程解释了为什么不能使用否定的字符类来匹配不后跟uq。负向前看提供了解决方案:q(?!u) .

Lookbehind具有相同的效果,但向后工作。它告诉regex引擎在字符串中暂时向后步进,检查后面的文本是否可以在那里匹配。(?<!a)b匹配前面没有"a""b",使用负向后看。它与cab不匹配,但与b(仅与b)在床上或债务中匹配。

您可以匹配&&&(或任何数量的重复),并且仅将单个替换为空字符串:

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

你可以使用这个正则表达式:@"(?<!&)&(?!&)"

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

你可以这样做:

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

这是尽可能通用的

我会使用这样的东西,这在我看来应该比使用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);
    }
}

我将从注释中贡献这句话:

在这种情况下,只有含有奇数个'&'的子字符串将被除最后一个'&'之外的所有'&'替换。. ",,,"是",和"answers",,,,"将",,,,"

这是一个使用平衡组的非常简洁的解决方案(尽管我不认为它特别干净,也不容易阅读)。

代码:

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

11222&&333&&44444&&&&55&&&&
<<p> ideone演示/kbd>
  1. 它总是匹配第一个&(未捕获)。
  2. 如果后面跟着偶数&,它们匹配并存储在$1中。第二组被第一组捕获,但随后被第二组减去。
  3. 但是,如果&有奇数,则可选组(?<-2>&)?不匹配,不减法。然后,$2将捕获一个额外的&

例如,匹配主题"&&&&",第一个字符被消耗,它不被捕获(1)。第二个和第三个字符被匹配,但是$2被减去(2)。对于最后一个字符,捕获$2 (3)。最后3个字符存储在$1中,$2中还有一个额外的&
然后,替换"$1$2" == "&&&&" .