在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# MVC 4 应用程序中的电子邮件地址验证:使用或不使用正则表达式 [重复]