C# 如何在句子结束前删除空格

C# 如何在句子结束前删除空格,c#,C#,我试图在句子结束前去掉空格,但没有成功。我想用分割函数来做,但是做得不好。我唯一成功的一件事就是在句子结束后加上空格。这是我的密码: static void Main(string[] args) { System.Windows.Forms.OpenFileDialog dlgOpen = new System.Windows.Forms.OpenFileDialog(); if (dlgOpen.ShowDialog() ==

我试图在句子结束前去掉空格,但没有成功。我想用分割函数来做,但是做得不好。我唯一成功的一件事就是在句子结束后加上空格。这是我的密码:

static void Main(string[] args)
        {
            System.Windows.Forms.OpenFileDialog dlgOpen = new System.Windows.Forms.OpenFileDialog();
            if (dlgOpen.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                StreamReader sr = new StreamReader(dlgOpen.FileName);
                string dat1 = sr.ReadToEnd();
                string dat2 = Path.GetDirectoryName(dlgOpen.FileName);
                string dat3 = Path.GetFileNameWithoutExtension(dlgOpen.FileName);
                string dat4 = Path.GetExtension(dlgOpen.FileName);

                dat2 = dat2 + "/" + dat3 + "_norm" + dat4;
                sz1(ref dat1);
                Console.Write(dat1);
                StreamWriter sw = new StreamWriter(dat2, false);
                sw.WriteLine(dat1);
                sw.Flush();
                sw.Close();

                Console.ReadLine();
            }
        }
        static void sz1(ref string dat1)
        {
            char[] ArrayCharacters = { '.', ':', ',', ';', '!', '?' };
            int i = -1;
            dat1 = dat1.Trim();

            for (int k = 0; k < dat1.Length; k++)
            {
                dat1 = dat1.Replace("  ", " ");
            }

            do
            {
                i = dat1.IndexOfAny(ArrayCharacters, i + 1);

                if (i != -1)
                {
                    dat1 = dat1.Insert((i + 1), " ");
                    dat1 = dat1.Replace("  ", " ");
                }
            } while (i != -1);

            do
            {
                i = dat1.IndexOfAny(ArrayCharacters, i + 1);

                if (i != -1)
                {
                    dat1 = dat1.Insert((i - 1), "  ");
                    dat1 = dat1.Replace("  ", " ");
                    dat1 = dat1.Remove(i - 1, 1);
                }
            } while (i != -1);
        }

如果只想从末端删除它们,可以使用:

if(myString.EndsWith(" ") == true)
{
    myString = myString.TrimEnd();
}
当然,你需要考虑结束符号。或者?,如果空格正好在该字符之前,您可能希望排除该字符

另一种办法是:

var keepTrimming = true;

while(keepTrimming == true)
{
    if(myString.EndsWith(" ") == true)
    {
        myString= myString.Remove(myString.Length - 1);
    }
    else
    {
        keepTrimming = false
    }
}

一种选择是使用正则表达式:

string pattern = "\\s+$";
string replacement = "";
Regex rgx = new Regex(pattern);
string result = rgx.Replace(dat1, replacement);

如果您只是在学习编程,那么您应该熟悉的一种解决方案是使用循环一次遍历字符串一个字符,因为我们正在检查字符串的结尾,所以向后遍历是有意义的

我从您的代码中假设,如果您在问题中澄清,您在句子末尾有一组允许的字符,并且您希望不使用这些字符,但删除任何额外的空格,那将是一件好事

那么,逻辑应该是从字符串的结尾开始,如果一个字符是有效的结尾字符,就不要管它。否则,如果它是一个空格,请将其删除。最后,如果两者都不是,那么我们就完了

下面是使用此逻辑的方法,以及用于存储结果的StringBuilder变量。从字符串的末尾开始,我们捕获最后一个字符,如果它们有效,则将它们添加到结果中,如果它们是空格,则跳过它们,直到到达一个常规字符,此时我们保留字符串的其余部分:

static string TrimEndSpaces(string input)
{
    // If the input is null, there's nothing to do - just return null
    if (input == null) return input;

    // Our array of valid ending punctuation
    char[] validEndingPunctuation = { '.', ':', ',', ';', '!', '?' };

    // This will contain our final result
    var result = new StringBuilder();

    // Walk backwards through the input string
    for (int i = input.Length - 1; i >= 0; i--)
    {
        if (validEndingPunctuation.Contains(input[i]))
        {
            // Valid character, so add it and keep going backwards
            result.Insert(0, input[i]);
            continue;
        }

        if (input[i] == ' ')
        {
            // Space character at end - skip it
            continue;
        }

        // Regular character found - we're done. Add the rest of the string
        result.Insert(0, input.Substring(0, i + 1));
        break;
    }

    return result.ToString();
}
下面是一个示例用法,一些测试语句的空格、有效字符、空字符串、空字符串等结尾不同:

private static void Main()
{
    var testInput = new List<string>
    {
        null,
        "",
        "       ",
        "Normal sentence test.",
        "Test with spaces   .",
        "Test with multiple ending chars  !?!?!",
        "Test with only spaces at end   ",
        "Test with spaces after punctuation.   ",
        "Test with mixed punctuation and spaces ! ? ! ? ! "
    };

    foreach (var test in testInput)
    {
        // Format output so we can "see" null and empty strings
        var original = test ?? "<null>";
        if (original.Length == 0) original = "<empty>";

        // Show original and the result. Wrap result in <> so we know where it ends.
        Console.WriteLine($"{original.PadRight(50, '-')} = <{TrimEndSpaces(test)}>");
    }

    GetKeyFromUser("\nDone! Press any key to exit...");
}
输出


你应该使用正则表达式。我还没有学会正则表达式,所以我不能在我的程序中使用它,我必须用字符串函数来解决它。为什么不使用someString。TrimEnd?Replace将用第二个字符串替换第一个字符串的所有实例。你不需要在循环中调用它。为了澄清,你是否试图删除句子最后一个单词和标点符号之间的空格,如?或.?.NET字符串是不可变的,因此这将不起作用。您至少需要将TrimEnd的结果分配给一个变量。在发布此消息后,您看到评论说您不能使用正则表达式。我将不讨论这个问题,因为这是一个现实世界的解决方案。正如其他人所指出的,string.TrimEnd也可以工作。然而,正则表达式在考虑其他字符时更灵活。