关于.net:替换C#字符串中的多个字符

Replace multiple characters in a C# string

有替代字符串的更好方法吗?

令我惊讶的是,Replace不包含字符数组或字符串数组。 我想我可以编写自己的扩展名,但我很好奇是否有更好的内置方法可以执行以下操作? 请注意,最后一个Replace是字符串而不是字符。

1
2
3
4
5
6
7
8
9
10
myString.Replace(';', '
'
).Replace(',', '
'
).Replace('
'
, '
'
).Replace('\t', '
'
).Replace(' ', '
'
).Replace("

"
,"
"
);

您可以使用替换正则表达式。

1
2
3
4
s/[;,\t
 ]|[
]{2}/
/g
  • 开头的s/表示搜索
  • []之间的字符是要搜索的字符(任何顺序)
  • 第二个/分隔搜索文本和替换文本

用英语写成:

"搜索;,\t
(空格)或正好两个连续的
,并将其替换为

在C#中,您可以执行以下操作:(在导入System.Text.RegularExpressions之后)

1
2
3
4
5
Regex pattern = new Regex("[;,\t
 ]|[
]{2}"
);
pattern.Replace(myString,"
"
);


如果您感觉特别聪明并且不想使用正则表达式:

1
2
3
4
5
6
7
8
9
10
11
12
char[] separators = new char[]{' ',';',',','
'
,'\t','
'
};

string s ="this;is,
a\t


test"
;
string[] temp = s.Split(separators, StringSplitOptions.RemoveEmptyEntries);
s = String.Join("
"
, temp);

您也可以毫不费力地将其包装在扩展方法中。

编辑:或等待2分钟,我最终还是写出来:)

1
2
3
4
5
6
7
8
9
10
public static class ExtensionMethods
{
   public static string Replace(this string s, char[] separators, string newVal)
   {
       string[] temp;

       temp = s.Split(separators, StringSplitOptions.RemoveEmptyEntries);
       return String.Join( newVal, temp );
   }
}

瞧...

1
2
3
4
5
6
7
8
9
10
11
char[] separators = new char[]{' ',';',',','
'
,'\t','
'
};
string s ="this;is,
a\t


test"
;

s = s.Replace(separators,"
"
);


您可以使用Linq的Aggregate函数:

1
2
3
4
5
6
7
8
string s ="the
quick\tbrown
dog,jumped;over the lazy fox."
;
char[] chars = new char[] { ' ', ';', ',', '
'
, '\t', '
'
};
string snew = chars.Aggregate(s, (c1, c2) => c1.Replace(c2, '
'
));

这是扩展方法:

1
2
3
4
public static string ReplaceAll(this string seed, char[] chars, char replacementCharacter)
{
    return chars.Aggregate(seed, (str, cItem) => str.Replace(cItem, replacementCharacter));
}

扩展方法的用法示例:

1
2
string snew = s.ReplaceAll(chars, '
'
);

这是最短的方法:

1
2
3
4
myString = Regex.Replace(myString, @"[;,\t
 ]|[
]{2}"
,"
"
);


哦,表演恐怖!
答案有点过时,但仍然...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
public static class StringUtils
{
    #region Private members

    [ThreadStatic]
    private static StringBuilder m_ReplaceSB;

    private static StringBuilder GetReplaceSB(int capacity)
    {
        var result = m_ReplaceSB;

        if (null == result)
        {
            result = new StringBuilder(capacity);
            m_ReplaceSB = result;
        }
        else
        {
            result.Clear();
            result.EnsureCapacity(capacity);
        }

        return result;
    }


    public static string ReplaceAny(this string s, char replaceWith, params char[] chars)
    {
        if (null == chars)
            return s;

        if (null == s)
            return null;

        StringBuilder sb = null;

        for (int i = 0, count = s.Length; i < count; i++)
        {
            var temp = s[i];
            var replace = false;

            for (int j = 0, cc = chars.Length; j < cc; j++)
                if (temp == chars[j])
                {
                    if (null == sb)
                    {
                        sb = GetReplaceSB(count);
                        if (i > 0)
                            sb.Append(s, 0, i);
                    }

                    replace = true;
                    break;
                }

            if (replace)
                sb.Append(replaceWith);
            else
                if (null != sb)
                    sb.Append(temp);
        }

        return null == sb ? s : sb.ToString();
    }
}

字符串只是不可变的char数组

您只需要使其可变即可:

  • 通过使用StringBuilder
  • 进入unsafe世界并玩指针(虽然很危险)

并尝试迭代字符数组最少的时间。请注意此处的HashSet,因为它避免遍历循环内的字符序列。如果您需要更快的查找,可以将HashSet替换为char的优化查找(基于array[256])。

StringBuilder的示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void MultiReplace(this StringBuilder builder,
    char[] toReplace,
    char replacement)
{
    HashSet<char> set = new HashSet<char>(toReplace);
    for (int i = 0; i < builder.Length; ++i)
    {
        var currentCharacter = builder[i];
        if (set.Contains(currentCharacter))
        {
            builder[i] = replacement;
        }
    }
}

编辑-优化版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static void MultiReplace(this StringBuilder builder,
    char[] toReplace,
    char replacement)
{
    var set = new bool[256];
    foreach (var charToReplace in toReplace)
    {
        set[charToReplace] = true;
    }
    for (int i = 0; i < builder.Length; ++i)
    {
        var currentCharacter = builder[i];
        if (set[currentCharacter])
        {
            builder[i] = replacement;
        }
    }
}

然后,您可以像这样使用它:

1
2
3
var builder = new StringBuilder("my bad,url&slugs");
builder.MultiReplace(new []{' ', '&', ','}, '-');
var result = builder.ToString();


您也可以简单地编写这些字符串扩展方法,并将它们放在解决方案中的某个位置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System.Text;

public static class StringExtensions
{
    public static string ReplaceAll(this string original, string toBeReplaced, string newValue)
    {
        if (string.IsNullOrEmpty(original) || string.IsNullOrEmpty(toBeReplaced)) return original;
        if (newValue == null) newValue = string.Empty;
        StringBuilder sb = new StringBuilder();
        foreach (char ch in original)
        {
            if (toBeReplaced.IndexOf(ch) < 0) sb.Append(ch);
            else sb.Append(newValue);
        }
        return sb.ToString();
    }

    public static string ReplaceAll(this string original, string[] toBeReplaced, string newValue)
    {
        if (string.IsNullOrEmpty(original) || toBeReplaced == null || toBeReplaced.Length <= 0) return original;
        if (newValue == null) newValue = string.Empty;
        foreach (string str in toBeReplaced)
            if (!string.IsNullOrEmpty(str))
                original = original.Replace(str, newValue);
        return original;
    }
}

像这样称呼他们:

1
"ABCDE".ReplaceAll("ACE","xy");

xyBxyDxy

还有这个:

1
"ABCDEF".ReplaceAll(new string[] {"AB","DE","EF" },"xy");

xyCxyF


使用RegEx.Replace,如下所示:

1
2
3
4
5
6
7
  string input ="This is   text with   far  too   much  " +
                "whitespace.";
  string pattern ="[;,]";
  string replacement ="
"
;
  Regex rgx = new Regex(pattern);
  string result = rgx.Replace(input, replacement);

这是有关RegEx的MSDN文档的更多信息。


1
2
3
4
5
6
7
string ToBeReplaceCharacters = @"~()@#$%&+,'"<>|;\/*?";
string fileName ="filename;with<bad:separators?";

foreach (var RepChar in ToBeReplaceCharacters)
{
    fileName = fileName.Replace(RepChar.ToString(),"");
}

明智的性能可能不是最好的解决方案,但它可以工作。

1
2
3
4
5
6
var str ="filename:with&bad$separators.txt";
char[] charArray = new char[] { '#', '%', '&', '{', '}', '\', '<', '>', '*', '?', '/', ' ', '$', '!', '\'', '"', ':', '@' };
foreach (var singleChar in charArray)
{
   str = str.Replace(singleChar, '_');
}