Existe-t-il un meilleur moyen de remplacer les chaînes?
Je suis surpris que Replace ne prenne pas dans un tableau de caractères ou un tableau de chaînes. Je suppose que je pourrais écrire ma propre extension, mais j’étais curieux de savoir s’il existe un moyen plus efficace de procéder comme suit. Remarquez que le dernier remplacement est une chaîne et non un caractère.
myString.Replace(';', '\n').Replace(',', '\n').Replace('\r', '\n').Replace('\t', '\n').Replace(' ', '\n').Replace("\n\n", "\n");
Vous pouvez utiliser une expression régulière de remplacement.
s/[;,\t\r ]|[\n]{2}/\n/g
s/
au début signifie une recherche[
et ]
sont les caractères à rechercher (dans n'importe quel ordre)/
délimite le texte à rechercher et le texte à remplacerEn anglais, cela se lit comme suit:
"Recherchez ;
ou ,
ou \t
ou \r
ou (espace) ou exactement deux
\n
séquentiels et remplacez-le par \n
"
En C #, vous pouvez effectuer les opérations suivantes: (après avoir importé System.Text.RegularExpressions
)
Regex pattern = new Regex("[;,\t\r ]|[\n]{2}");
pattern.Replace(myString, "\n");
Si vous vous sentez particulièrement malin et que vous ne voulez pas utiliser Regex:
char[] separators = new char[]{' ',';',',','\r','\t','\n'};
string s = "this;is,\ra\t\n\n\ntest";
string[] temp = s.Split(separators, StringSplitOptions.RemoveEmptyEntries);
s = String.Join("\n", temp);
Vous pouvez également inclure cela dans une méthode d'extension avec peu d'effort.
Edit: Ou bien attendez 2 minutes et je finirai quand même par l'écrire :)
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 );
}
}
Et voila ...
char[] separators = new char[]{' ',';',',','\r','\t','\n'};
string s = "this;is,\ra\t\n\n\ntest";
s = s.Replace(separators, "\n");
Vous pouvez utiliser la fonction Aggréger de Linq:
string s = "the\nquick\tbrown\rdog,jumped;over the lazy fox.";
char[] chars = new char[] { ' ', ';', ',', '\r', '\t', '\n' };
string snew = chars.Aggregate(s, (c1, c2) => c1.Replace(c2, '\n'));
Voici la méthode d'extension:
public static string ReplaceAll(this string seed, char[] chars, char replacementCharacter)
{
return chars.Aggregate(seed, (str, cItem) => str.Replace(cItem, replacementCharacter));
}
C'est le moyen le plus court:
myString = Regex.Replace(myString, @"[;,\t\r ]|[\n]{2}", "\n");
Ohhh, l'horreur de la performance! La réponse est un peu dépassée, mais quand même ...
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();
}
}
Vous avez juste besoin de le rendre mutable:
StringBuilder
unsafe
et jouez avec les pointeurs (dangereux cependant)et essayez de parcourir le tableau de caractères le moins de fois possible.
Exemple avec StringBuilder
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;
}
}
}
Ensuite, il vous suffit de l'utiliser comme ça:
var builder = new StringBuilder("my bad,url&slugs");
builder.MultiReplace(new []{' ', '&', ','}, '-');
var result = builder.ToString();
Vous pouvez aussi simplement écrire ces méthodes d'extension string , et les mettre quelque part dans votre solution:
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;
}
}
Appelez-les comme ça:
"ABCDE".ReplaceAll("ACE", "xy");
xyBxyDxy
Et ça:
"ABCDEF".ReplaceAll(new string[] { "AB", "DE", "EF" }, "xy");
xyCxyF
Utilisez RegEx.Replace, quelque chose comme ceci:
string input = "This is text with far too much " +
"whitespace.";
string pattern = "[;,]";
string replacement = "\n";
Regex rgx = new Regex(pattern);
Voici plus d'informations sur ceci Documentation MSDN pour RegEx.Replace
Performance-Wise, cela n’est peut-être pas la meilleure solution, mais cela fonctionne.
var str = "filename:with&bad$separators.txt";
char[] charArray = new char[] { '#', '%', '&', '{', '}', '\\', '<', '>', '*', '?', '/', ' ', '$', '!', '\'', '"', ':', '@' };
foreach (var singleChar in charArray)
{
str = str.Replace(singleChar, '_');
}
string ToBeReplaceCharacters = @"~()@#$%&+,'"<>|;\/*?";
string fileName = "filename;with<bad:separators?";
foreach (var RepChar in ToBeReplaceCharacters)
{
fileName = fileName.Replace(RepChar.ToString(), "");
}