C# 有没有更整洁的方法来消除用户输入中的大量空白?

C# 有没有更整洁的方法来消除用户输入中的大量空白?,c#,.net,C#,.net,我需要创建一个从用户输入中删除大量空白的方法,这样就不会弄乱通过UI或报表显示的信息的格式。我希望阻止用户使用制表符、多个空格和一行中两个以上的回车符。这是我目前的解决方案(效果很好),但有人有更整洁的吗?我的主要挑战是确保用户可以使用单回车或双回车: public static class StringHelper { private static readonly string SingleBreakGuid = Guid.NewGuid().ToString(); priv

我需要创建一个从用户输入中删除大量空白的方法,这样就不会弄乱通过UI或报表显示的信息的格式。我希望阻止用户使用制表符、多个空格和一行中两个以上的回车符。这是我目前的解决方案(效果很好),但有人有更整洁的吗?我的主要挑战是确保用户可以使用单回车或双回车:

public static class StringHelper
{
    private static readonly string SingleBreakGuid = Guid.NewGuid().ToString();
    private static readonly string DoubleBreakGuid = Guid.NewGuid().ToString();

    /// <summary>
    /// Limits character spacing to single spacing.  Limits line spacing to no more than double line spacing. 
    /// </summary>
    /// <param name="sourceString">The source string that will be used to calculate the result.</param>
    /// <returns>A string with single spacing between characters and no more than double line spacing.</returns>
    public static string RemoveExtensiveWhiteSpace(this string sourceString)
    {
        // Normalise breaks, so that they are all \r\n
        var normalisedString = sourceString.NormaliseLineBreaks();

        // Replace multiple spaces and tabs with a single space
        var singleSpacedString = string.Join(" ", normalisedString.Split(new[] { " ", "\t" }, StringSplitOptions.RemoveEmptyEntries));

        // Trim all of the sub-strings between breaks - this will also empty any whitespace between breaks
        var trimmedString = string.Join("\r\n",
            singleSpacedString.Split(new[] { "\r\n" }, StringSplitOptions.None)
            .Select(s => s.Trim()));

        // The logic requires that the user can use one or two carriage returns, which difficult to achieve by splitting and re-joining.
        // Replace the double and single carriage returns with respective Guids
        var guidNotationString = trimmedString.Replace("\r\n\r\n", DoubleBreakGuid).Replace("\r\n", SingleBreakGuid);

        // Merge trailing DoubleBreakGuid with trailing SingleBreakGuid into just a DoubleBreakGuid.
        var includesTripleBreaks = guidNotationString.Replace(DoubleBreakGuid + SingleBreakGuid, DoubleBreakGuid);

        // Replace groups of DoubleBreakGuid with a double break
        var includesDoubleBreaks = string.Join("\r\n\r\n",
            includesTripleBreaks.Split(new[] { DoubleBreakGuid }, StringSplitOptions.RemoveEmptyEntries));

        // Replace groups of SingleBreakGuid with single breaks
        var includesSingleBreaks = string.Join("\r\n",
            includesDoubleBreaks.Split(new[] { SingleBreakGuid }, StringSplitOptions.RemoveEmptyEntries));

        return includesSingleBreaks;
    }

    public static string NormaliseLineBreaks(this string sourceString)
    {
        return sourceString
            .Replace("\r\n", "\n")
            .Replace("\n\r", "\n")
            .Replace("\r", "\n")
            .Replace("\n", "\r\n");
    }
}
公共静态类StringHelper
{
私有静态只读字符串SingleBreakGuid=Guid.NewGuid().ToString();
私有静态只读字符串DoubleBreakGuid=Guid.NewGuid().ToString();
/// 
///将字符间距限制为单个间距。将行距限制为不超过两倍行距。
/// 
///将用于计算结果的源字符串。
///字符之间只有一个间距且不超过两倍行距的字符串。
公共静态字符串RemoveExtensiveWhiteSpace(此字符串源字符串)
{
//使中断正常化,使其全部正常\r\n
var normalisedString=sourceString.NormaliseLineBreaks();
//将多个空格和选项卡替换为单个空格
var singleSpacedString=string.Join(“,normalisedString.Split(new[]{”“,“\t”},StringSplitOptions.removemptyEntries));
//修剪打断之间的所有子字符串-这也将清空打断之间的任何空白
var trimmedString=string.Join(“\r\n”,
singleSpacedString.Split(新[]{“\r\n”},StringSplitOptions.None)
.选择(s=>s.Trim());
//逻辑要求用户可以使用一个或两个回车,这很难通过拆分和重新加入来实现。
//用相应的guid替换双回车和单回车
var guidNotationString=trimmedString.Replace(“\r\n\r\n”,DoubleBreakGuid)。Replace(“\r\n”,SingleBreakGuid);
//将尾部DoubleBreakGuid与尾部SingleBreakGuid合并为一个DoubleBreakGuid。
var includesTripleBreaks=guidNotationString.Replace(DoubleBreakGuid+SingleBreakGuid,DoubleBreakGuid);
//用双断点替换DoubleBreakGuid的组
var includesDoubleBreaks=string.Join(“\r\n\r\n”,
includesTripleBreaks.Split(新[]{DoubleBreakGuid},StringSplitOptions.RemoveEmptyEntries));
//将SingleBreakGuid组替换为SingleBreakGuid组
var includesSingleBreaks=string.Join(“\r\n”,
includeDoubleBreaks.Split(新[]{SingleBreakGuid},StringSplitOptions.RemoveEmptyEntries));
退货包括单件退货;
}
公共静态字符串NormaliseLineBreaks(此字符串源字符串)
{
返回源字符串
.Replace(“\r\n”,“\n”)
.替换(“\n\r”,“\n”)
.替换(“\r”和“\n”)
.替换(“\n”和“\r\n”);
}
}

您可以使用迭代方法将多个换行符减少为一个双换行符。与其使用奇怪的guid替换,不如使用以下内容:

var collapsedString = trimmedString.Replace("\r\n\r\n\r\n","\r\n\r\n");
while(collapsedString.Length < trimmedString.Length)
{
  trimmedString = collapsedString;
  collapsedString = trimmedString.Replace("\r\n\r\n\r\n","\r\n\r\n");
}
var collapsedString=trimmedString.Replace(“\r\n\r\n\r\n”和“\r\n\r\n”);
while(collapsedString.Length
您的代码包含许多替换…,每个替换都需要迭代整个输入字符串,并根据匹配条件创建一个新字符串

在这里,我编写了一个只循环一次的代码,并根据需要跳过重复的空格(
“,\t”
)和换行符(
“\r',”\r\n',“\n\r'
):

必须注意的是,如果我们有一个已知的换行符,代码可能会更简单。但是我没有在这里的代码中使用
NormaliseLineBreaks
func

public static class StringHelper
{

    public static string RemoveExtraWhiteSpace(this string s)
    {
        int n = s.Length;
        StringBuilder sb = new StringBuilder(n); //to make output
        int nLineBreaks = 2; //number of repetitive line breaks, assume there were 2 enter chars before begining of s (to avoid adding initial line breaks or spaces)
        bool prevCharWasCrLf = false; //we can't use nEneter for this purpose as it skip white spaces between line breaks
        char ch1, ch = '\0'; //ch1 is prev char, ch is current char

        for (int i = 0; i < n; i++) //iterate through chars
        {
            ch1 = ch; ch = s[i]; //get next char

            if (ch == '\r' || ch == '\n')
            {
                if (prevCharWasCrLf && ch != ch1) { prevCharWasCrLf = false; continue; } //this char is second of CrLf pair, ignore it as we already treat it
                //if (prevCharWasCrLf == false || ch == ch1) /if we prefer don't use continue
                prevCharWasCrLf = true;
                nLineBreaks++;
                if (nLineBreaks <= 2) //append new line break if we have less than 2 
                {
                    if (sb.Length > 0 && sb[sb.Length - 1] == ' ') sb.Length--;  //remove prev space as it was before an enter
                    sb.Append("\r\n");
                }
            }
            else
            {
                if (ch == ' ' || ch == '\t')
                {
                    if (nLineBreaks == 0 && ch1 != ' ' && ch1 != '\t') sb.Append(' '); //don't add more space after another space or enter
                }
                else
                {
                    nLineBreaks = 0; sb.Append(ch); //its a normal char, add it to output
                }
                prevCharWasCrLf = false;
            }
        }

        return sb.ToString().TrimEnd('\r', '\n'); //if we don't use nReturn = 2 at begining, we shall run: .Trim('\r', '\n', ' ', '\t');
    }
}
公共静态类StringHelper
{
公共静态字符串RemoveExtraWhiteSpace(此字符串为s)
{
int n=s.长度;
StringBuilder sb=新建StringBuilder(n);//进行输出
int nLineBreaks=2;//重复换行的次数,假设在开始s之前有2个enter字符(以避免添加初始换行符或空格)
bool-prevCharWasCrLf=false;//我们不能使用nEneter,因为它会跳过换行符之间的空格
char ch1,ch='\0';//ch1是上一个char,ch是当前char
for(int i=0;i//删除上一个空格,就像在输入之前一样
sb.追加(“\r\n”);
}
}
其他的
{
如果(ch=''| | ch='\t')
{
如果(nLineBreaks==0&&ch1!=''&&ch1!='\t')sb.Append('');//不要在另一个空格后添加更多空格或输入
}
其他的
{
nLineBreaks=0;sb.Append(ch);//这是一个普通字符,将其添加到输出
}
prevCharWasCrLf=假;
}
}
返回sb.ToString().TrimEnd('\r','\n');//如果我们在开始时不使用nReturn=2,我们将运行:.Trim('\r','\n','\t');
}
}
它可能需要一些微调,但它在我的测试中起作用

此外,我知道它不是一个短代码,但在我看来,它更干净,最重要的是:它有更好的性能

public string RemoveExtensiveWhiteSpace(string s) { s = Regex.Replace(s, @"\r\n|\n\r|\n|\r", "\r\n"); //normalize all type of line breaks to \r\n s = Regex.Replace(s, @"[ \t]+", " "); // \t+|[\t ]{2,} s = s.Replace("\r\n ", "\r\n").Replace(" \r\n", "\r\n"); //Regex.Replace(s, @"(\r\n | \n\r)", "\r\n") s = Regex.Replace(s, @"(\r\n){2,}", "\r\n\r\n"); //replace 2+ new line breaks with 2 return s.Trim('\r', '\n', ' '); //remove initial & final white space chars }