【问题标题】:Keep only numeric value from a string?只保留字符串中的数值?
【发布时间】:2013-10-03 19:31:16
【问题描述】:

我有一些这样的字符串

string phoneNumber = "(914) 395-1430";

我想去掉括号和破折号,换句话说,只保留数值。

所以输出可能是这样的

9143951430

如何获得所需的输出?

【问题讨论】:

  • 即使你没有正则表达式的经验,你至少应该做一些研究。答案的数量与问题的难度成反比。
  • 总有像你这样的人抱怨问题,这是一个问答网站,如果我知道我不会问谢谢!
  • 我不是在抱怨,我只是让你知道已经有这种东西了。 SO 的一项政策是将所有重复的问题重定向到一个主要问题。重复的问题经常被这样删除。
  • @SystemDown 我知道怎么做,但如果我不确定我会问,请参阅我最终使用不需要正则表达式的答案。这是我完全不知道的事情
  • 为什么这个答案被关闭了?我从谷歌来到这里寻找“c#从字符串中提取数字”,这个完全有效、简单和普遍的问题被关闭为“离题”什么主题?编程主题?我认为它在主题上非常好。到底是什么

标签: c# regex string numeric


【解决方案1】:

您执行以下任一操作:

  • 使用正则表达式。您可以将正则表达式与任一

    • 一个否定字符类,它定义了你不想要的字符(那些不是十进制数字的字符):

      private static readonly Regex rxNonDigits = new Regex( @"[^\d]+");
      

      在这种情况下,您可以采取以下任一方法:

      // simply replace the offending substrings with an empty string
      private string CleanStringOfNonDigits_V1( string s )
      {
        if ( string.IsNullOrEmpty(s) ) return s ;
        string cleaned = rxNonDigits.Replace(s, "") ;
        return cleaned ;
      }
      
      // split the string into an array of good substrings
      // using the bad substrings as the delimiter. Then use
      // String.Join() to splice things back together.
      private string CleanStringOfNonDigits_V2( string s )
      {
        if (string.IsNullOrEmpty(s)) return s;
        string cleaned = String.Join( rxNonDigits.Split(s) );
        return cleaned ;
      }
      
    • 一个定义你想要什么的正字符集(十进制数字):

      private static Regex rxDigits = new Regex( @"[\d]+") ;
      

      在这种情况下,您可以这样做:

      private string CleanStringOfNonDigits_V3( string s )
      {
        if ( string.IsNullOrEmpty(s) ) return s ;
        StringBuilder sb = new StringBuilder() ;
        for ( Match m = rxDigits.Match(s) ; m.Success ; m = m.NextMatch() )
        {
          sb.Append(m.Value) ;
        }
        string cleaned = sb.ToString() ;
        return cleaned ;
      }
      
  • 您也不需要使用正则表达式。

    • 您可以直接使用 LINQ,因为字符串是 IEnumerable<char>

      private string CleanStringOfNonDigits_V4( string s )
      {
        if ( string.IsNullOrEmpty(s) ) return s;
        string cleaned = new string( s.Where( char.IsDigit ).ToArray() ) ;
        return cleaned;
      }
      
    • 如果您只处理西方字母,您将看到的唯一十进制数字是 ASCII,跳过 char.IsDigit 可能会给您带来一点性能:

      private string CleanStringOfNonDigits_V5( string s )
      {
        if (string.IsNullOrEmpty(s)) return s;
        string cleaned = new string(s.Where( c => c-'0' < 10 ).ToArray() ) ;
        return cleaned;
      }
      
  • 最后,您可以简单地遍历字符串,丢弃您不想要的数字,如下所示:

    private string CleanStringOfNonDigits_V6( string s )
    {
      if (string.IsNullOrEmpty(s)) return s;
      StringBuilder sb = new StringBuilder(s.Length) ;
      for (int i = 0; i < s.Length; ++i)
      {
        char c = s[i];
        if ( c < '0' ) continue ;
        if ( c > '9' ) continue ;
        sb.Append(s[i]);
      }
      string cleaned = sb.ToString();
      return cleaned;
    }
    

    或者这个:

    private string CleanStringOfNonDigits_V7(string s)
    {
      if (string.IsNullOrEmpty(s)) return s;
      StringBuilder sb = new StringBuilder(s);
      int j = 0 ;
      int i = 0 ;
      while ( i < sb.Length )
      {
        bool isDigit = char.IsDigit( sb[i] ) ;
        if ( isDigit )
        {
          sb[j++] = sb[i++];
        }
        else
        {
          ++i ;
        }
      }
      sb.Length = j;
      string cleaned = sb.ToString();
      return cleaned;
    }
    

从代码的清晰和整洁的角度来看,版本 1 就是您想要的。很难击败一个班轮。

如果性能很重要,我怀疑版本 7(最后一个版本)是赢家。它会创建一个临时对象——StringBuilder(),并在 StringBuilder 的就地缓冲区中就地进行转换。

其他选项都做得更多。

【讨论】:

  • 哇,多么详细的答案啊,你回答的比我的问题还多,这给了我更多的选择,也理解像你这样的用户正在使 SO 成为一个伟大的社区。非常感谢!!!
【解决方案2】:

使用正则表达式

 string result = Regex.Replace(phoneNumber, @"[^\d]", "");

【讨论】:

  • 不错的单线。或... @"[^\d]+" ...(“+”添加到表达式中)每次替换一次收集更多字符。尚未测试这是否会产生速度差异。
【解决方案3】:

试试这样的

  return new String(input.Where(Char.IsDigit).ToArray());

【讨论】:

    【解决方案4】:
    string phoneNumber = "(914) 395-1430";
    var numbers = String.Join("", phoneNumber.Where(char.IsDigit));
    

    【讨论】:

      【解决方案5】:

      他意味着一切@glen

      Regex rgx = new Regex(@"\D");
      str = rgx.Replace(str, "");
      

      【讨论】:

      • @ 很重要!
      • 谢谢两位。但你能记得我为什么吗?前段时间用过,不记得为什么?因为说它是文本:/
      • @ 将文本转换为原始文本,因此您无需转义反斜杠。否则,您将被程序尝试替换并最终得到一个正则表达式 D
      • 是的,记得。再次感谢。
      【解决方案6】:

      您可以使用 LINQ 方法代替正则表达式:

      phoneNumber = String.Concat(phoneNumber.Where(c => c >= '0' && c <= '9'));
      

      或:

      phoneNumber = String.Concat(phoneNumber.Where(Char.IsDigit));
      

      【讨论】:

        猜你喜欢
        • 2016-03-16
        • 1970-01-01
        • 1970-01-01
        • 2017-07-17
        • 2011-12-04
        • 1970-01-01
        • 1970-01-01
        • 2018-05-27
        相关资源
        最近更新 更多