C#正则表达式:删除混合多种语言、Unicode字母的文本中的非打印字符和控制字符。

35

我希望你能帮忙,因为我不知道要使用哪个字符范围,或者是否有类似于ruby中我找到的[[:cntrl:]]这样的字符类?

所谓的非可打印字符是指删除所有在IE输出时未显示在输入字符串中的字符。请注意,我在寻找一个C#正则表达式,我的代码没有问题。


哪些字符应该是不可打印的?你需要构建正则表达式字符类。也许,你只需要使用\p{C}(= 不可见控制字符和未使用的代码点),或者\p{Cc}(仅控制字符,请参见http://www.regular-expressions.info/posixbrackets.html)。 - Wiktor Stribiżew
4个回答

100

您可以使用以下方式删除所有控制字符和其他不可打印字符:

s = Regex.Replace(s, @"\p{C}+", string.Empty);

\p{C} Unicode类别匹配所有控制字符,甚至包括ASCII表之外的字符,因为在.NET中,Unicode类别默认是Unicode感知的。

分解为子类别

  • 要仅匹配基本控制字符,可以使用\p{Cc}+,参见Other, Control Unicode类别中的65个字符。它等价于[\u0000-\u0008\u000E-\u001F\u007F-\u0084\u0086-\u009F \u0009-\u000D \u0085]+正则表达式。
  • 要只匹配161个其他格式字符,包括众所周知的软连字号 (\u00AD),零宽度空格 (\u200B),零宽度非连接符 (\u200C),零宽度连接符 (\u200D),从左到右标记 (\u200E),和从右到左标记 (\u200F),请使用 \p{Cf}+。其中包括天文位置代码点的等价物是一个(?:[\xAD\u0600-\u0605\u061C\u06DD\u070F\u08E2\u180E\u200B-\u200F\u202A-\u202E\u2060-\u2064\u2066-\u206F\uFEFF\uFFF9-\uFFFB]|\uD804[\uDCBD\uDCCD]|\uD80D[\uDC30-\uDC38]|\uD82F[\uDCA0-\uDCA3]|\uD834[\uDD73-\uDD7A]|\uDB40[\uDC01\uDC20-\uDC7F])+正则表达式。
  • 要匹配137468个其他、私有使用控制码点,可以使用\p{Co}+或其等价物包括天文位置代码点,(?:[\uE000-\uF8FF]|[\uDB80-\uDBBE\uDBC0-\uDBFE][\uDC00-\uDFFF]|[\uDBBF\uDBFF][\uDC00-\uDFFD])+
  • 要匹配包括一些表情符号在内的2048个其他、代理代码点,可以使用\p{Cs}+[\uD800-\uDFFF]+正则表达式。

我为这种有趣的方法和Unicode兼容性点赞,尽管我认为在某些应用程序(例如我的应用程序)中,制表符、回车、换行等可以被解释为“可打印的”,因此我更喜欢这里所展示的方法。 - SteveCinq
11
那么您也可以使用@"[\p{C}-[\r\n\t]]+"并将任何其他符号添加到嵌套括号中,以避免进行替换。 - Wiktor Stribiżew
2
这里是支持的Unicode通用类别列表 https://learn.microsoft.com/en-us/dotnet/standard/base-types/character-classes-in-regular-expressions#SupportedUnicodeGeneralCategories 提示:请查看下方的支持的命名块 - Doomjunky
@Doomjunky 这是一个很好的参考,只需注意这些 Unicode 类别类并不匹配 Unicode 代码点,它们只匹配代码单元,这就是为什么我添加了包含所有相关代码点的十六进制模式。这些代码点可以在 Unicode Utilities: UnicodeSet 上获取。 - Wiktor Stribiżew
TIL 星界平面 Unicode。 - HackSlash

6

非常感谢,我会尝试这个。我只需要正则表达式,代码已经有了,我的担心是不会在过程中丢失任何可打印字符 :) - user7150219
我认为你会得到输出:"Tkrgsmrgs",你能举个例子说明你想要删除哪些字符吗? - Yanga
那么这不是我想要的,这正是我担心的,屏幕上失去了字符。我的目标是删除屏幕上没有显示但存在且无用的字符,例如,在JAVA中,我可以使用\p{Print}来保留所有这些字符。 - user7150219
这对我有用。我的问题不同,因此我需要支持UTF-8,但我也想剥离控制字符。 - Bryan Harrington

2

删除所有控制字符和其他不可打印字符

Regex.Replace(s, @"\p{C}+", String.Empty);

只删除控制字符(如果您不想删除表情符号)

Regex.Replace(s, @"\p{Cc}+", String.Empty);

2

您可以尝试这个:

    public static string TrimNonAscii(this string value)
    {
        string pattern = "[^ -~]*";
        Regex reg_exp = new Regex(pattern);
        return reg_exp.Replace(value, "");
    }

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