有没有更好的方法来替换字符串?
我很惊讶Replace不接受字符数组或字符串数组。我想我可以写我自己的扩展,但我很好奇是否有更好的内置方式来做以下工作?注意最后一个Replace是一个字符串而不是字符。
myString.Replace(';', '\n').Replace(',', '\n').Replace('\r', '\n').Replace('\t', '\n').Replace(' ', '\n').Replace("\n\n", "\n");
有没有更好的方法来替换字符串?
我很惊讶Replace不接受字符数组或字符串数组。我想我可以写我自己的扩展,但我很好奇是否有更好的内置方式来做以下工作?注意最后一个Replace是一个字符串而不是字符。
myString.Replace(';', '\n').Replace(',', '\n').Replace('\r', '\n').Replace('\t', '\n').Replace(' ', '\n').Replace("\n\n", "\n");
当前回答
我知道这个问题非常古老,但我想提供两个更有效的选择:
首先,Paul Walls发布的扩展方法很好,但可以通过使用StringBuilder类来提高效率,StringBuilder类类似于字符串数据类型,但专门用于需要多次更改字符串值的情况。下面是我用StringBuilder做的扩展方法的一个版本:
public static string ReplaceChars(this string s, char[] separators, char newVal)
{
StringBuilder sb = new StringBuilder(s);
foreach (var c in separators) { sb.Replace(c, newVal); }
return sb.ToString();
}
我运行了这个操作10万次,使用StringBuilder花费了73毫秒,而使用string花费了81毫秒。所以区别通常是可以忽略不计的,除非你运行很多操作或使用一个巨大的字符串。
其次,这里有一个你可以使用的1线循环:
foreach (char c in separators) { s = s.Replace(c, '\n'); }
我个人认为这是最好的选择。它非常高效,并且不需要编写扩展方法。在我的测试中,这种方法在63毫秒内运行了10万次迭代,是最高效的。 下面是一个上下文中的例子:
string s = "this;is,\ra\t\n\n\ntest";
char[] separators = new char[] { ' ', ';', ',', '\r', '\t', '\n' };
foreach (char c in separators) { s = s.Replace(c, '\n'); }
本例的前两行要归功于Paul Walls。
其他回答
可以使用replace正则表达式。
s/[;,\t\r ]|[\n]{2}/\n/g
S /在开头表示搜索 [和]之间的字符是要搜索的字符(以任何顺序) 第二个/分隔搜索文本和替换文本
用英语来说,这是:
“寻找;或者,或者\t \r或者(空格)或者恰好两个连续的\n,然后把它替换成\n
在c#中,你可以做以下事情:(在导入system . text . regulareexpressions之后)
Regex pattern = new Regex("[;,\t\r ]|[\n]{2}");
pattern.Replace(myString, "\n");
没有“替换”(仅限Linq):
string myString = ";,\r\t \n\n=1;;2,,3\r\r4\t\t5 6\n\n\n\n7=";
char NoRepeat = '\n';
string ByeBye = ";,\r\t ";
string myResult = myString.ToCharArray().Where(t => !"STOP-OUTSIDER".Contains(t))
.Select(t => "" + ( ByeBye.Contains(t) ? '\n' : t))
.Aggregate((all, next) => (
next == "" + NoRepeat && all.Substring(all.Length - 1) == "" + NoRepeat
? all : all + next ) );
我知道这个问题非常古老,但我想提供两个更有效的选择:
首先,Paul Walls发布的扩展方法很好,但可以通过使用StringBuilder类来提高效率,StringBuilder类类似于字符串数据类型,但专门用于需要多次更改字符串值的情况。下面是我用StringBuilder做的扩展方法的一个版本:
public static string ReplaceChars(this string s, char[] separators, char newVal)
{
StringBuilder sb = new StringBuilder(s);
foreach (var c in separators) { sb.Replace(c, newVal); }
return sb.ToString();
}
我运行了这个操作10万次,使用StringBuilder花费了73毫秒,而使用string花费了81毫秒。所以区别通常是可以忽略不计的,除非你运行很多操作或使用一个巨大的字符串。
其次,这里有一个你可以使用的1线循环:
foreach (char c in separators) { s = s.Replace(c, '\n'); }
我个人认为这是最好的选择。它非常高效,并且不需要编写扩展方法。在我的测试中,这种方法在63毫秒内运行了10万次迭代,是最高效的。 下面是一个上下文中的例子:
string s = "this;is,\ra\t\n\n\ntest";
char[] separators = new char[] { ' ', ';', ',', '\r', '\t', '\n' };
foreach (char c in separators) { s = s.Replace(c, '\n'); }
本例的前两行要归功于Paul Walls。
哦,表演太恐怖了! 答案有点过时了,但仍然……
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();
}
}
就性能而言,这可能不是最好的解决方案,但它确实有效。
var str = "filename:with&bad$separators.txt";
char[] charArray = new char[] { '#', '%', '&', '{', '}', '\\', '<', '>', '*', '?', '/', ' ', '$', '!', '\'', '"', ':', '@' };
foreach (var singleChar in charArray)
{
str = str.Replace(singleChar, '_');
}