如何删除多个重复& C#中字符串不必要的标点符号?

时间:2017-10-29 12:46:29

标签: c# regex string

考虑这样的字符串:

<compilation> 
    <assemblies> 
        <remove assembly="Microsoft.VisualStudio.Web.PageInspector.Loader,
    Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </assemblies> 
</compilation>

我想在最后替换不必要的标点符号,使其看起来像这样:

"This is a string....!"
"This is another...!!"
"What is this..!?!?"
...
// There are LOTS of examples of weird/angry sentence-endings like the ones above.

我基本上做的是:   - 按空间划分   - 检查字符串中的最后一个字符是否包含标点符号   - 开始用下面的模式替换

我尝试了一个非常大的&#34; .Replace(字符串,字符串)&#34;功能,但它不起作用 - 我猜想必须有一个更简单的正则表达式。

文档:

  

返回一个新字符串,其中当前实例中所有出现的指定字符串都被另一个指定的字符串替换。

以及:

  

因为此方法返回修改后的字符串,所以可以将对Replace方法的连续调用链接在一起,以对原始字符串执行多次替换。

这里有什么不对。

编辑:所有提议的解决方案都运行良好!非常感谢你! 这个是我项目最适合的解决方案:

"This is a string!"
"This is another!"
"What is this?"

3 个答案:

答案 0 :(得分:3)

您的解决方案几乎正常(demo),唯一的问题是从不同位置开始匹配相同的序列。例如,最后一行中的..!?!?不是替换列表的一部分,因此..!?!?会被两个单独的匹配替换,从而在输出中生成??。 / p>

看起来你的策略非常简单:在多个标点符号链中,最后一个角色获胜。您可以使用正则表达式进行替换:

[!?.]*([!?.])

并将其替换为$1,即具有最后一个字符的捕获组:

string s;
while ((s = Console.ReadLine()) != null) {
    s = Regex.Replace(s, "[!?.]*([!?.])", "$1");
    Console.WriteLine(s);
}

Demo

答案 1 :(得分:2)

简单地

[.?!]*(?=[.?!]$)

应该为你做。像

Regex re = new Regex("[.?!]*(?=[.?!]$)");
Console.WriteLine(re.Replace("This is a string....!", ""));

这取代了所有标点符号,但最后没有任何标点符号。

[.?!]*匹配任意数量的连续标点符号,(?=[.?!]$)是一个正向前瞻,确保它在字符串末尾留下一个。

See it here at ideone

答案 2 :(得分:1)

或者你可以在没有regExps的情况下完成:

    string TrimPuncMarks(string str)
    {
        HashSet<char> punctMarks = new HashSet<char>() {'.', '!', '?'};

        int i = str.Length - 1;
        for (; i >= 0; i--)
        {
            if (!punctMarks.Contains(str[i]))
                break;
        }

        // the very last punct mark or null if there were no any punct marks in the end
        char? suffix = i < str.Length - 1 ? str[str.Length - 1] : (char?)null;

        return str.Substring(0, i+1) + suffix;
    }

    Debug.Assert("What is this?" == TrimPuncMarks("What is this..!?!?"));
    Debug.Assert("What is this" == TrimPuncMarks("What is this"));
    Debug.Assert("What is this." == TrimPuncMarks("What is this."));