Bir dizede birden çok boşluğu C # 'da yalnızca bir boşlukla nasıl değiştirebilirim?
Misal:
1 2 3 4 5
olabilir:
1 2 3 4 5
Bir dizede birden çok boşluğu C # 'da yalnızca bir boşlukla nasıl değiştirebilirim?
Misal:
1 2 3 4 5
olabilir:
1 2 3 4 5
Yanıtlar:
string sentence = "This is a sentence with multiple spaces";
RegexOptions options = RegexOptions.None;
Regex regex = new Regex("[ ]{2,}", options);
sentence = regex.Replace(sentence, " ");
Kullanmayı seviyorum:
myString = Regex.Replace(myString, @"\s+", " ");
Çünkü herhangi bir beyaz alanın (örn. Sekmeler, yeni satırlar, vb.) Çalışmalarını yakalar ve bunları tek bir boşlukla değiştirir.
string xyz = "1 2 3 4 5";
xyz = string.Join( " ", xyz.Split( new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries ));
Bence Matt'in cevabı en iyisi, ama bunun doğru olduğuna inanmıyorum. Yeni satırları değiştirmek istiyorsanız şunu kullanmalısınız:
myString = Regex.Replace(myString, @"\s+", " ", RegexOptions.Multiline);
Bunlardan çok daha basit:
while(str.Contains(" ")) str = str.Replace(" ", " ");
Replace()
Yöntem bu yüzden döngü (ve bir bütün dize yeniden tahsis) dizede eşleştirilmiş alanların her örneği için değil, belirli bir dizeye iki boşluk tüm tekrarlarını idare edecek. Yeni bir tahsis hepsini halledecektir. Döngüyü yalnızca 3 veya daha fazla boşluk olduğunda yeniden çalıştırırız; bu, birçok giriş kaynağı için daha nadir bir durumdur. Verileriniz için bir sorun haline geldiğini gösterebiliyorsanız, yeni bir dize oluşturucuya karakter karakter itmek için durum makinesini yazın.
Regex basit görevlerle bile oldukça yavaş olabilir. Bu, herhangi birinden kullanılabilecek bir uzantı yöntemi oluşturur string
.
public static class StringExtension
{
public static String ReduceWhitespace(this String value)
{
var newString = new StringBuilder();
bool previousIsWhitespace = false;
for (int i = 0; i < value.Length; i++)
{
if (Char.IsWhiteSpace(value[i]))
{
if (previousIsWhitespace)
{
continue;
}
previousIsWhitespace = true;
}
else
{
previousIsWhitespace = false;
}
newString.Append(value[i]);
}
return newString.ToString();
}
}
Bu şekilde kullanılır:
string testValue = "This contains too much whitespace."
testValue = testValue.ReduceWhitespace();
// testValue = "This contains too much whitespace."
myString = Regex.Replace(myString, " {2,}", " ");
Sevmeyenler için Regex
, burada aşağıdakileri kullanan bir yöntem vardır StringBuilder
:
public static string FilterWhiteSpaces(string input)
{
if (input == null)
return string.Empty;
StringBuilder stringBuilder = new StringBuilder(input.Length);
for (int i = 0; i < input.Length; i++)
{
char c = input[i];
if (i == 0 || c != ' ' || (c == ' ' && input[i - 1] != ' '))
stringBuilder.Append(c);
}
return stringBuilder.ToString();
}
Testlerimde, bu yöntem statik olarak derlenmiş Regex'e kıyasla çok büyük küçük-orta ölçekli dizelerle ortalama 16 kat daha hızlıydı. Derlenmemiş veya statik olmayan bir Regex ile karşılaştırıldığında, bu daha da hızlı olmalıdır.
O olmadığını, unutmayın değildir başında veya sonunda boşluk, böyle sadece birden fazla kopyasını çıkarın.
Bunu tek satırlık bir çözümde yapabilirsiniz!
string s = "welcome to london";
s.Replace(" ", "()").Replace(")(", "").Replace("()", " ");
İsterseniz diğer köşeli parantezleri (hatta diğer karakterleri) seçebilirsiniz.
"wel()come to london)("
olur "wel come to london"
. Çok sayıda parantez kullanmayı deneyebilirsiniz. Bu yüzden ((((()))))
yerine ()
ve )))))(((((
yerine kullanın )(
. Yine de çalışır. Yine de, eğer dize içerir ((((()))))
veya )))))(((((
bu başarısız olur.
Bu, Regex
her çağrıldığında sınıfın yeni bir örneğini oluşturduğundan, yalnızca bir kez yapıyorsanız kullanılması gereken daha kısa bir sürümdür .
temp = new Regex(" {2,}").Replace(temp, " ");
Düzenli ifadeler hakkında fazla bilgi sahibi değilseniz, kısa bir açıklama:
{2,}
Bunu önceki karakter için regex arama yapar ve 2 ve sınırsız saatler arasında alt dizeleri bulur. .Replace(temp, " ")
Bir boşlukla dize sıcaklığında tüm eşleşmeleri değiştirir.
Bunu birden çok kez kullanmak istiyorsanız, derleme zamanında regex IL oluşturduğundan daha iyi bir seçenek var:
Regex singleSpacify = new Regex(" {2,}", RegexOptions.Compiled);
temp = singleSpacify.Replace(temp, " ");
no Regex, no Linq ... önde gelen ve sondaki boşlukları kaldırır ve gömülü birden çok boşluk parçasını bir boşluğa indirir
string myString = " 0 1 2 3 4 5 ";
myString = string.Join(" ", myString.Split(new char[] { ' ' },
StringSplitOptions.RemoveEmptyEntries));
sonuç: "0 1 2 3 4 5"
Joel'e göre diğer cevapları birleştirmek ve umarım ilerledikçe biraz geliştirmek:
Bunu aşağıdakilerle yapabilirsiniz Regex.Replace()
:
string s = Regex.Replace (
" 1 2 4 5",
@"[ ]{2,}",
" "
);
Veya String.Split()
:
static class StringExtensions
{
public static string Join(this IList<string> value, string separator)
{
return string.Join(separator, value.ToArray());
}
}
//...
string s = " 1 2 4 5".Split (
" ".ToCharArray(),
StringSplitOptions.RemoveEmptyEntries
).Join (" ");
Sadece sevdiğim yeni bir yazı yazdım Join
, bu yüzden tekrar cevaplayacağımı düşündüm:
public static string Join<T>(this IEnumerable<T> source, string separator)
{
return string.Join(separator, source.Select(e => e.ToString()).ToArray());
}
Bununla ilgili harika şeylerden biri, öğeler üzerinde ToString () öğesini çağırarak dize olmayan koleksiyonlarla çalışmasıdır. Kullanım hala aynı:
//...
string s = " 1 2 4 5".Split (
" ".ToCharArray(),
StringSplitOptions.RemoveEmptyEntries
).Join (" ");
// Mysample string
string str ="hi you are a demo";
//Split the words based on white sapce
var demo= str .Split(' ').Where(s => !string.IsNullOrWhiteSpace(s));
//Join the values back and add a single space in between
str = string.Join(" ", demo);
//output: string str ="hi you are a demo";
Bunun oldukça eski olduğunu biliyorum, ama neredeyse aynı şeyi başarmaya çalışırken bununla karşılaştım. Bu çözümü RegEx Buddy'de buldum. Bu desen tüm çift boşlukları tek boşluklarla değiştirecek ve aynı zamanda ön ve arka boşlukları kırpacaktır.
pattern: (?m:^ +| +$|( ){2,})
replacement: $1
Boş alanla uğraştığımız için okumak biraz zor, bu yüzden yine "boşluklar" yerine "_" ile değiştiriliyor.
pattern: (?m:^_+|_+$|(_){2,}) <-- don't use this, just for illustration.
"(? M:" yapısı "çok satırlı" seçeneğini etkinleştirir.Genel olarak daha fazla kendi içinde kalması için genellikle desenin içine hangi seçenekleri dahil etmeyi severim.
Birçok cevap doğru çıktıyı sağlıyor, ancak en iyi performansları arayanlar için Nolanar'ın cevabını (performans için en iyi cevaptı) yaklaşık% 10 iyileştirdim .
public static string MergeSpaces(this string str)
{
if (str == null)
{
return null;
}
else
{
StringBuilder stringBuilder = new StringBuilder(str.Length);
int i = 0;
foreach (char c in str)
{
if (c != ' ' || i == 0 || str[i - 1] != ' ')
stringBuilder.Append(c);
i++;
}
return stringBuilder.ToString();
}
}
Bununla boşlukları kaldırabilirim
while word.contains(" ") //double space
word = word.Replace(" "," "); //replace double space by single space.
word = word.trim(); //to remove single whitespces from start & end.
bu yöntemi dene
private string removeNestedWhitespaces(char[] st)
{
StringBuilder sb = new StringBuilder();
int indx = 0, length = st.Length;
while (indx < length)
{
sb.Append(st[indx]);
indx++;
while (indx < length && st[indx] == ' ')
indx++;
if(sb.Length > 1 && sb[0] != ' ')
sb.Append(' ');
}
return sb.ToString();
}
şöyle kullanın:
string test = removeNestedWhitespaces("1 2 3 4 5".toCharArray());
İşte Nolonar orijinal cevabı üzerinde küçük bir değişiklik .
Karakterin sadece boşluk değil boşluk olup olmadığını kontrol etmek için şunu kullanın:
Birden çok boşluk karakterini tek bir boşlukla değiştirir.
public static string FilterWhiteSpaces(string input)
{
if (input == null)
return string.Empty;
var stringBuilder = new StringBuilder(input.Length);
for (int i = 0; i < input.Length; i++)
{
char c = input[i];
if (i == 0 || !char.IsWhiteSpace(c) || (char.IsWhiteSpace(c) &&
!char.IsWhiteSpace(strValue[i - 1])))
stringBuilder.Append(c);
}
return stringBuilder.ToString();
}
Eski skool:
string oldText = " 1 2 3 4 5 ";
string newText = oldText
.Replace(" ", " " + (char)22 )
.Replace( (char)22 + " ", "" )
.Replace( (char)22 + "", "" );
Assert.That( newText, Is.EqualTo( " 1 2 3 4 5 " ) );
Normal ifadeler kullanmadan:
while (myString.IndexOf(" ", StringComparison.CurrentCulture) != -1)
{
myString = myString.Replace(" ", " ");
}
Kısa dizelerde kullanmak için Tamam, ancak çok fazla alana sahip uzun dizelerde kötü performans gösterecektir.
Dizeler için genişletme yöntemi olarak StringBuilder ve Enumerable.Aggregate () karışımı :
using System;
using System.Linq;
using System.Text;
public static class StringExtension
{
public static string StripSpaces(this string s)
{
return s.Aggregate(new StringBuilder(), (acc, c) =>
{
if (c != ' ' || acc.Length > 0 && acc[acc.Length-1] != ' ')
acc.Append(c);
return acc;
}).ToString();
}
public static void Main()
{
Console.WriteLine("\"" + StringExtension.StripSpaces("1 Hello World 2 ") + "\"");
}
}
Giriş:
"1 Hello World 2 "
Çıktı:
"1 Hello World 2 "