【问题标题】:How can I strip punctuation from a string?如何从字符串中去除标点符号?
【发布时间】:2009-01-07 19:05:05
【问题描述】:

对于这个问题的希望在 30 秒内获得答案的部分,我专门寻找 C#

但在一般情况下,去除任何语言中的标点符号的最佳方法是什么?

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

相关:Strip Punctuation in Python

【问题讨论】:

  • 不同的语言实际上是不同的,我认为您所问的问题没有答案。您可以询问特定的语言,或者哪种语言最适合这种操作。

标签: c# string


【解决方案1】:
new string(myCharCollection.Where(c => !char.IsPunctuation(c)).ToArray());

【讨论】:

  • 是的。它为我在下面发布的字符串操作提供动力。
  • LinQ 总是让我惊叹。
  • 太棒了。少即是多。
  • 不适用于 $ 或 ^,也许更多。我坚持使用 ^[a-zA-Z][a-zA-Z0-9]*$
  • 对于$或^你可以使用!char.IsSymbol(c)验证。仅作记录
【解决方案2】:

为什么不简单:

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

RegEx 的使用通常比简单的字符操作要慢。那些 LINQ 操作对我来说看起来有点矫枉过正。而且你不能在 .NET 2.0 中使用这样的代码...

【讨论】:

  • 请注意,这种方法还允许您将标点符号替换为(例如)空格。用于标记化。
【解决方案3】:

描述意图、最容易阅读 (恕我直言) 和最佳表现:

 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 的算法,这是发布的一堆中表现最好的。

【讨论】:

  • 有趣的花絮:以下不是标点符号:$^+|=
【解决方案4】:

假设“最好”意味着“最简单”,我建议使用类似这样的内容:

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

此示例适用于 Java,,但所有足够现代的正则表达式引擎都应支持此(或类似的东西)。

编辑:Unicode-Aware 版本是这样的:

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

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

【讨论】:

  • C# 没有 Punct 类,但它有 P
【解决方案5】:

您可以使用 regex.replace 方法:

 replace(YourString, RegularExpressionWithPunctuationMarks, Empty String)

由于这会返回一个字符串,因此您的方法将如下所示:

 string s = Regex.Replace("Hello!?!?!?!", "[?!]", "");

如果你愿意,你可以用更复杂的东西替换“[?!]”:

(\p{P})

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

【讨论】:

  • +1 用于使用 unicode 字符类。简洁、精确、美观。
【解决方案6】:

这个帖子太老了,但如果我不发布更优雅的 (IMO) 解决方案,那就太失职了。

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

这是没有 WTF 的 LINQ。

【讨论】:

    【解决方案7】:

    基于 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; }));
    

    【讨论】:

    • 我知道;正确的?我的爱好是在 Linq 中对代码犯错。但是,请务必让它变得更好。
    • 请寻求精神科帮助。
    • 这是 s 中长度的二次方;如果将长度加倍,代码将慢四倍,因为字符串的 + 运算符必须复制字符串:/
    【解决方案8】:

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

    我想的另一种方式是 regex.replace 并在其中包含所有适当的标点符号的正则表达式。

    【讨论】:

      【解决方案9】:

      这是使用 linq 的一种稍微不同的方法。我喜欢 AviewAnew 的,但这避免了聚合

              string myStr = "Hello there..';,]';';., Get rid of Punction";
      
              var s = from ch in myStr
                      where !Char.IsPunctuation(ch)
                      select ch;
      
              var bytes = UnicodeEncoding.ASCII.GetBytes(s.ToArray());
              var stringResult = UnicodeEncoding.ASCII.GetString(bytes);
      

      【讨论】:

      • 为什么IEnumerable&lt;char&gt; 到数组到字节到字符串的转换,为什么不只是new String(s.ToArray())?或者这就是新字符串在引擎盖下的作用?
      【解决方案10】:

      如果你想用它来标记文本,你可以使用:

      new string(myText.Select(c => char.IsPunctuation(c) ? ' ' : c).ToArray())
      

      【讨论】:

        【解决方案11】:

        对于任何想通过 RegEx 执行此操作的人:

        这段代码显示了完整的正则表达式替换过程,并给出了一个示例正则表达式,它只在字符串中保留字母、数字和空格 - 用空字符串替换所有其他字符:

        //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;
        

        【讨论】:

          【解决方案12】:

          我遇到了同样的问题,并且担心每次检查都调用 IsPunctuation 会影响性能。

          我发现了这个帖子:http://www.dotnetperls.com/char-ispunctuation

          跨界:char.IsPunctuation 还在 ASCII 之上处理 Unicode。 该方法匹配一堆字符,包括控制字符。顾名思义,这种方法既繁重又昂贵。

          最重要的是,我最终没有选择它,因为它对我的 ETL 流程的性能影响。

          我选择了 dotnetperls 的自定义实现。

          仅供参考,这里是从前面的答案中推导出来的一些代码,用于获取所有标点符号(不包括控制符号)的列表:

          var punctuationCharacters = new List<char>();
          
                  for (int i = char.MinValue; i <= char.MaxValue; i++)
                  {
                      var character = Convert.ToChar(i);
          
                      if (char.IsPunctuation(character) && !char.IsControl(character))
                      {
                          punctuationCharacters.Add(character);
                      }
                  }
          
                  var commaSeparatedValueOfPunctuationCharacters = string.Join("", punctuationCharacters);
          
                  Console.WriteLine(commaSeparatedValueOfPunctuationCharacters);
          

          干杯, 安德鲁

          【讨论】:

            【解决方案13】:
            $newstr=ereg_replace("[[:punct:]]",'',$oldstr);
            

            【讨论】:

              【解决方案14】:

              对于长字符串我使用这个:

              var normalized = input
                              .Where(c => !char.IsPunctuation(c))
                              .Aggregate(new StringBuilder(),
                                         (current, next) => current.Append(next), sb => sb.ToString());
              

              性能比使用字符串连接好得多(尽管我同意它不太直观)。

              【讨论】:

                【解决方案15】:

                这是从用户给出的字符串中删除标点符号的简单代码

                导入需要的库

                    import string
                

                以字符串格式向用户询问输入

                    strs = str(input('Enter your string:'))
                
                    for c in string.punctuation:
                        strs= strs.replace(c,"")
                    print(f"\n Your String without punctuation:{strs}")
                

                【讨论】:

                  【解决方案16】:
                  #include<string>
                      #include<cctype>
                      using namespace std;
                  
                      int main(int a, char* b[]){
                      string strOne = "H,e.l/l!o W#o@r^l&d!!!";
                      int punct_count = 0;
                  
                  cout<<"before : "<<strOne<<endl;
                  for(string::size_type ix = 0 ;ix < strOne.size();++ix)   
                  {   
                      if(ispunct(strOne[ix])) 
                      {
                              ++punct_count;  
                              strOne.erase(ix,1); 
                              ix--;
                      }//if
                  }
                      cout<<"after : "<<strOne<<endl;
                                    return 0;
                      }//main
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2016-02-20
                    • 2010-09-20
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2011-01-15
                    • 1970-01-01
                    • 2013-10-08
                    相关资源
                    最近更新 更多