【问题标题】:Regex to remove all special characters from string?正则表达式从字符串中删除所有特殊字符?
【发布时间】:2011-03-19 05:17:30
【问题描述】:

我完全不会使用正则表达式,因此我需要一些帮助来解决我认为最好通过使用正则表达式来解决的问题。

我有 C# 中的字符串列表:

List<string> lstNames = new List<string>();
lstNames.add("TRA-94:23");
lstNames.add("TRA-42:101");
lstNames.add("TRA-109:AD");

foreach (string n in lstNames) {
  // logic goes here that somehow uses regex to remove all special characters
  string regExp = "NO_IDEA";
  string tmp = Regex.Replace(n, regExp, "");
}

我需要能够遍历列表并返回没有任何特殊字符的每个项目。例如,项目一是“TRA9423”,项目二是“TRA42101”,项目三是TRA109AD。

有没有一个正则表达式可以帮我完成这个?

此外,该列表包含 4000 多个项目,因此我需要尽可能高效和快速地进行搜索和替换。

编辑: 我应该指定 a-z、A-Z 和 0-9 之外的任何字符在我的情况下都是特殊的。

【问题讨论】:

  • 4000 是极少数的项目。为什么答案是高效和快速的而不是可读性和可维护性如此重要?您是否在这里衡量过性能问题?
  • @Mark - 这只是我的无知表现,我想。 4000 在我看来很多,但我显然错了。我没有做过任何基准测试,但无论如何,正则表达式似乎非常快,所以我认为我不需要为了加快速度而搞砸。我实际上稍微简化了我的示例,因为我不想不必要地使我的问题复杂化。我实际上有一个复杂类对象的列表,并且我正在使用带有委托函数的 .FindAll 来查找所有匹配项。正则表达式在我的类的一个属性中发挥作用,该属性使用正则表达式来操作委托函数的某个字符串。
  • 谢谢大家的帮助!对于像你们这样的天才来说,所有的问题都像这样容易吗? :D

标签: c# regex string


【解决方案1】:

这真的取决于你对特殊字符的定义。我发现在大多数情况下,白名单而不是黑名单是最好的方法:

tmp = Regex.Replace(n, "[^0-9a-zA-Z]+", "");

您应该小心当前的方法,因为以下两项将被转换为相同的字符串,因此无法区分:

"TRA-12:123"
"TRA-121:23"

【讨论】:

  • + 量词是多余的。如果字符匹配,它也会在这些连续序列中匹配。
  • @Daniel,我希望+ 可以使操作大大加快,当然这并不重要,除非您处理的事情很大。
  • 这两个项目最终是否相同并不重要,因为我正在进行模糊匹配,并且我希望返回多个项目。 List lstPax = lstReports.FindAll(delegate(PdfAndXml o) { return (o.Packed.Contains(findTxt)); }); Packed 是我使用正则表达式来操作 PdfAndXml 类的某个字符串属性的属性。
  • 喜欢“白名单”的想法!
  • 所以 ^ 表示不在正则表达式中?
【解决方案2】:

应该这样做:

[^a-zA-Z0-9]

基本上它匹配所有非字母数字字符。

【讨论】:

    【解决方案3】:

    [^a-zA-Z0-9] 是一个匹配任何非字母数字字符的字符类。

    或者,[^\w\d] 做同样的事情。

    用法:

    string regExp = "[^\w\d]";
    string tmp = Regex.Replace(n, regExp, "");
    

    【讨论】:

    • 我在regexpal.com上测试了这两个版本,发现“[^\w\d]”不会匹配下划线字符,而[^a-zA-Z0-9]会匹配。跨度>
    【解决方案4】:

    你可以使用:

    string regExp = "\\W";
    

    这相当于丹尼尔的“[^a-zA-Z0-9]

    \W 匹配任何非单词字符。等效于 Unicode 类别[^\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}]

    【讨论】:

    • 也匹配 _ 所以这里不是很完美。
    • 嗯,你是对的 - 从描述中不会这样认为。很好发现。
    【解决方案5】:

    根据您对“特殊字符”的定义,我认为“[^a-zA-Z0-9]”可能会奏效。这将找到任何不是小写字母、大写字母或数字的内容。

    【讨论】:

    • 哦,我注意到答案中出现了一种模式。
    【解决方案6】:

    出于我的目的,我想要所有英文 ASCII 字符,所以这行得通。

    html = Regex.Replace(html, "[^\x00-\x80]+", "")
    

    【讨论】:

      【解决方案7】:
      tmp = Regex.Replace(n, @"\W+", "");
      

      \w 匹配字母、数字和下划线,\W 是否定版本。

      【讨论】:

      • 既然您将 _ 定义为特殊的,您应该选择其他答案之一:)
      【解决方案8】:

      如果您不想使用正则表达式,那么另一种选择是使用

      char.IsLetterOrDigit
      

      您可以使用它来遍历字符串的每个字符,并且仅在为 true 时返回。

      【讨论】:

        【解决方案9】:
        public static string Letters(this string input)
        {
            return string.Concat(input.Where(x => char.IsLetter(x) && !char.IsSymbol(x) && !char.IsWhiteSpace(x)));
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-05-26
          • 2017-12-11
          • 2021-03-13
          • 2014-01-10
          • 2017-06-22
          • 1970-01-01
          相关资源
          最近更新 更多