如何从字符串中去除标点符号?

76

对于这个问题中希望在30秒内得到答案的部分,我特别寻找C#方面的解决方案。

但是在一般情况下,如何最好地去除任何语言中的标点符号?

我应该补充说明: 理想情况下,解决方案不需要枚举所有可能的标点符号。

相关: Python中去除标点符号的最佳方法


不同的编程语言实际上是不同的,我认为你问的问题没有一个答案。你可以询问特定的语言,或者哪种语言最适合进行那种操作。 - David Thornley
16个回答

120
new string(myCharCollection.Where(c => !char.IsPunctuation(c)).ToArray());

1
是的。它正在驱动我下面发布的字符串操作。 - Tom Ritter
10
LinQ令我惊叹不已。 - Dermot
精妙。少即是多。 - Saeed Neamati
不适用于 $ 或 ^,可能还有其他字符。我会坚持使用 ^[a-zA-Z][a-zA-Z0-9]*$。 - Stuart Dobson
PhoneNumberTextBox.Text = new string(PhoneNumberTextBox.Text.Where(c => !char.IsPunctuation(c)).ToArray()).Replace(" ",""); - dnennis
2
对于 $ 或 ^,您可以使用 !char.IsSymbol(c) 进行验证。仅供记录。 - Razvan Dumitru

25

为什么不直接这样写:

string s = "sxrdct?fvzguh,bij.";
var sb = new StringBuilder();
foreach (char c in s) { if (!char.IsPunctuation(c)) sb.Append(c); }
s = sb.ToString();

使用正则表达式通常比简单的字符操作慢。而那些 LINQ 操作看起来像是杀鸡焉用牛刀。而且你不能在 .NET 2.0 中使用这样的代码...


请注意,这种方法还可以让您将标点符号替换为(例如)空格。对于分词非常有用。 - user565869

16

描述意图,易于阅读(仅为个人意见)且性能最佳:

 s = s.StripPunctuation();

实现:

public static class StringExtension
{
    public static string StripPunctuation(this string s)
    {
        var sb = new StringBuilder();
        foreach (char c in s)
        {
            if (!char.IsPunctuation(c))
                sb.Append(c);
        }
        return sb.ToString();
    }
}

这里使用了Hades32的算法,该算法是发布的一堆算法中最优秀的。


有趣的小知识:以下字符不是标点符号:$^+|<>= - Brian Low

14

假如“best”指的是“最简单”,我建议使用类似这样的方法:

String stripped = input.replaceAll("\\p{Punct}+", "");

这个示例是针对Java的,但所有足够现代的正则表达式引擎都应该支持这个(或类似的)。

编辑:Unicode感知版本如下:

String stripped = input.replaceAll("\\p{P}+", "");

第一个版本只考虑ASCII中包含的标点符号。


1
C# 没有 Punct 类,但它确实有 P - JProgrammer

9
你可以使用regex.replace方法:
 replace(YourString, RegularExpressionWithPunctuationMarks, Empty String)

由于此处返回一个字符串,因此您的方法将类似于以下内容:
 string s = Regex.Replace("Hello!?!?!?!", "[?!]", "");

如果您想要的话,您可以将“[?!]”替换为更复杂的内容:

(\p{P})

这应该可以找到任何标点符号。


使用Unicode字符类,简洁、精确、美观。 - Tom Anderson

6

这个帖子太老了,但我认为我应该发布一个更优雅的解决方案。

string inputSansPunc = input.Where(c => !char.IsPunctuation(c)).Aggregate("", (current, c) => current + c);

这是没有令人困惑的LINQ。

4

在GWLlosa的想法的基础上,我想出了一个相当丑陋但可行的解决方案:

string s = "cat!";
s = s.ToCharArray().ToList<char>()
      .Where<char>(x => !char.IsPunctuation(x))
      .Aggregate<char, string>(string.Empty, new Func<string, char, string>(
             delegate(string s, char c) { return s + c; }));

2
我知道,对吧?我的一个爱好是在Linq中犯下代码罪行。但请务必让它变得更好。 - Tom Ritter
5
请寻求精神科医生的帮助。 - Tom Anderson
这是关于字符串长度的二次方;如果你将长度加倍,代码会变慢四倍,因为字符串的 + 运算符必须复制字符串 :/ - Clément

2
如果您想用它来对文本进行分词,可以使用以下方法:
new string(myText.Select(c => char.IsPunctuation(c) ? ' ' : c).ToArray())

2

如果有人想通过正则表达式来实现这个功能:

以下代码展示了完整的正则表达式替换过程,并提供了一个样例正则表达式,只保留字符串中的字母、数字和空格 - 用空字符串替换所有其他字符:

//Regex to remove all non-alphanumeric characters
System.Text.RegularExpressions.Regex TitleRegex = new 
System.Text.RegularExpressions.Regex("[^a-z0-9 ]+", 
System.Text.RegularExpressions.RegexOptions.IgnoreCase);

string ParsedString = TitleRegex.Replace(stringToParse, String.Empty);

return ParsedString;

2

最简单的方法是使用string.replace。

另一种想象中的方法是使用regex.replace,并将你的正则表达式与所有适当的标点符号放在一起。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接