在c#中使用/不使用正则表达式清除不需要的十六进制字符[重复]

Posted

技术标签:

【中文标题】在c#中使用/不使用正则表达式清除不需要的十六进制字符[重复]【英文标题】:Clearing unwanted hex characters with/without regex in c# [duplicate] 【发布时间】:2020-12-19 15:26:43 【问题描述】:

我必须以更好的方式从异常消息中清除十六进制字符。现在它可以手动替换字符,这似乎完全是这样的灾难:

            var clearedStr = str.Replace(Convert.ToString((char)0x01), "")
            .Replace(Convert.ToString((char)0x02), "")
            .Replace(Convert.ToString((char)0x03), "")
            .Replace(Convert.ToString((char)0x04), "")
            .Replace(Convert.ToString((char)0x05), "")
            .Replace(Convert.ToString((char)0x06), "")
            .Replace(Convert.ToString((char)0x07), "")
            .Replace(Convert.ToString((char)0x08), "")
            .Replace(Convert.ToString((char)0x0B), "")
            .Replace(Convert.ToString((char)0x0C), "")
            .Replace(Convert.ToString((char)0x0E), "")
            .Replace(Convert.ToString((char)0x0F), "")
            .Replace(Convert.ToString((char)0x10), "")
            .Replace(Convert.ToString((char)0x11), "")
            .Replace(Convert.ToString((char)0x12), "")
            .Replace(Convert.ToString((char)0x13), "")
            .Replace(Convert.ToString((char)0x14), "")
            .Replace(Convert.ToString((char)0x15), "")
            .Replace(Convert.ToString((char)0x16), "")
            .Replace(Convert.ToString((char)0x17), "")
            .Replace(Convert.ToString((char)0x18), "")
            .Replace(Convert.ToString((char)0x19), "")
            .Replace(Convert.ToString((char)0x1a), "")
            .Replace(Convert.ToString((char)0x1b), "")
            .Replace(Convert.ToString((char)0x1c), "")
            .Replace(Convert.ToString((char)0x1d), "")
            .Replace(Convert.ToString((char)0x1e), "")
            .Replace(Convert.ToString((char)0x84), "")
            .Replace(Convert.ToString((char)0x86), "")
            .Replace(Convert.ToString((char)0x87), "")
            .Replace(Convert.ToString((char)0x88), "")
            .Replace(Convert.ToString((char)0x89), "");

例如带有十六进制字符的消息:

实际上我写了一个正则表达式,但它适用于像 0x1e 这样的十六进制字符,但不适用于它的等价物:

但我需要找到这些字符,而不是十六进制等效字符:

"","'","ƒ","","","'","","š","^","‰","Š","‹","Œ" ,"","„", "†", "‡"

相同的字符及其符号:

"RS: , PU1 : ', NBH : ƒ, US : , ESC : , PU2: ', GS : , SCI:š,HTS:^,HTJ:‰,VTS:Š,PLD:‹,PLU:Œ,SUB:,IND:„,SSA:†,ESA:‡”

正则表达式是我写的:

http://regexstorm.net/tester?p=%5b0-9%5dx%5b0-9A-F%5d&i=0x1e+0x91+0x1c+0x83

另外,我需要涵盖所有这类角色,而不是一堆。

【问题讨论】:

ASCII 编码将删除所有不可打印的字符。 @jdweng 这不是真的。 ASCII 包含一堆不可打印的字符,想到换行符 (0x9) 以及 a bunch more 这个怎么样..检查这个正则表达式。 [0-9]x[0-9A-Fa-f].+? 这可能会有所帮助:***.com/questions/3253247/… @jdweng 我尝试使用在线编码器。我需要显示此数据,因此如果我编码此文本,我需要解码以向用户显示消息。所以当我解码时,它可能会再次变成初始字符。但我仍然需要对其进行详细测试。 【参考方案1】:

作为MindSwipe suggests,您可以使用\pC 匹配任何控制字符。

但是你不需要添加很多代码来减去一些你可能想要保留的字符,使用字符类减法:

var output = Regex.Replace(YourTextVariable, @"[\pC-[\t\r\n]]+", "");

这将匹配一个或多个不同于制表符、回车和换行的控制字符。

【讨论】:

这大大优于我的回答。我还学到了一些关于正则表达式的新东西,谢谢。 @cansu 你真的应该接受这个答案而不是我的答案 你是对的@MindSwipe 这个答案实际上更准确。也感谢您的贡献。【参考方案2】:

在进一步阅读之前,请查看 Ryszard Czech 的 answer,了解如何在不添加任何多余代码的情况下执行此操作


这可以通过替换字符串中的每个控制字符来实现,幸运的是正则表达式有答案:

var s = "a \nb" + Convert.ToString((char)0x1b) + Convert.ToString((char) 0x1e);
Regex.Replace(s, @"\pC+", String.Empty);

@"\pC+" 匹配所有控制字符。请注意,这也将匹配换行符 (\n),这意味着您的输出不会有任何换行符,如您在 this 示例中所见。如果您希望保留换行符,则必须首先将字符串拆分为一个数组,并在每一行上添加Regex.Replace,然后将它们重新组合在一起。像这样:

var lines = s.Split(new[]  Environment.NewLine , StringSplitOptions.None);
var sb = new StringBuilder();

foreach (var line in lines)

    sb.AppendLine(Regex.Replace(line, @"\pC+", String.Empty));


s = sb.ToString();

这会留下一个尾随换行符,可以像这样轻松删除:

if (sb[sb.Length - 1] == '\n')
    sb.Remove(sb.Length - 1, 1);

在致电sb.ToString() 之前执行此操作。 Here 是一个演示这个的 dotnetfiddle

【讨论】:

哇,当我尝试在线正则表达式测试器时,它似乎工作正常。我将对其进行详细测试,以便检查您的答案。谢谢。 @cansu 我添加了一个指向 dotnetfiddle 的链接来演示它的工作原理 是的,似乎异常消息完全没有错误的控制字符。谢谢。【参考方案3】:

有时一个好的旧foreach 是正确的方法。怎么样:

 private static readonly char[] CharsToReplace =
 
     '\x02',
     '\x03',
     '\x04',
     '\x05',
     '\x06',
     '\x07',
     '\x08',
     '\x0B',
     '\x0C',
     '\x0E',
     '\x0F',
     '\x10',
     '\x11',
     '\x12',
     '\x13',
     '\x14',
     '\x15',
     '\x16',
     '\x17',
     '\x18',
     '\x19',
     '\x1a',
     '\x1b',
     '\x1c',
     '\x1d',
     '\x1e',
     '\x84',
     '\x86',
     '\x87',
     '\x88',
     '\x89',
 ;

public static string ReplaceNonPrintables(string stringToProcess)

    StringBuilder buf = new StringBuilder(stringToProcess.Length);
    foreach (var c in stringToProcess)
    
        if (!CharsToReplace.Contains(c))
        
            buf.Append(c)
        
    

    return buf.ToString();

【讨论】:

谢谢,如果任何其他想法不能解决问题,这可能是解决方案。 缺点是 O(NxM) (其中 N 是字符串长度,M 是要删除的字符数)。使用Hashset 可能会更快

以上是关于在c#中使用/不使用正则表达式清除不需要的十六进制字符[重复]的主要内容,如果未能解决你的问题,请参考以下文章

需要在 C# 正则表达式中提取文本

C# MVC 4 应用程序中的电子邮件地址验证:使用或不使用正则表达式 [重复]

Java 和 C# 正则表达式不产生相同的结果

C#:更改正则表达式的 NumberDecimalSeparator

十进制数的正则表达式

java正则表达式