我有一个方法检查,如果一个字符串是一个有效的十六进制字符串:
public bool IsHex(string value)
{
if (string.IsNullOrEmpty(value) || value.Length % 2 != 0)
return false;
return
value.Substring(0, 2) == "0x" &&
value.Substring(2)
.All(c => (c >= '0' && c <= '9') ||
(c >= 'a' && c <= 'f') ||
(c >= 'A' && c <= 'F'));
}
Run Code Online (Sandbox Code Playgroud)
规则是:
表达式必须由偶数个十六进制数字组成(0-9,AF,af).
字符0x必须是表达式中的前两个字符.
我敢肯定它可以用更清洁,更有效的方式重写正则表达式.
你可以帮帮我吗?
更新问题后,适用于您的新正则表达式应为:
^0x(?:[0-9A-Fa-f]{2})+$
Run Code Online (Sandbox Code Playgroud)
我(?:用于非捕获分组以提高效率的地方.这{2}意味着您需要前面两个表达式(即两个十六进制字符),这+意味着您需要一个或多个十六进制字符.请注意,这不允许0x作为有效值.
"Oded"提到了一些关于效率的问题.我不知道你的要求,所以我认为这更像是一种心灵锻炼而不是其他任何东西.只要最小的匹配正则表达式,正则表达式就会跳跃.例如,在10,000个大小为50-5000个字符的变量输入字符串上尝试我自己的正则表达式,一切正确,它在1.1秒内运行.
当我尝试以下正则表达式时:
^0x(?:[0-9A-Fa-f]{32})+(?:[0-9A-Fa-f]{2})+$
Run Code Online (Sandbox Code Playgroud)
它的运行速度提高了约40%,在0.67秒内完成.不过要小心.了解您的输入是知道如何编写有效的正则表达式.例如,如果正则表达式失败,它将进行大量的反向跟踪.如果我的输入字符串中有一半的长度不正确,则对于相同的输入,运行时间会爆炸到大约34秒或3000%(!).
如果大多数输入字符串很大,它变得更加棘手.如果您输入的99%是有效长度,则所有输入都是> 4130个字符,而只有少数不是,写入
^0x(?:[0-9A-Fa-f]{4096})+^0x(?:[0-9A-Fa-f]{32})+(?:[0-9A-Fa-f]{2})+$
Run Code Online (Sandbox Code Playgroud)
效率更高,时间更长.但是,如果许多不正确length % 2 = 0,由于反向跟踪,这会产生反效果.
最后,如果大多数字符串满足偶数规则,并且只有一些或多个字符串包含错误字符,则速度会提高:包含错误字符的输入越多,性能越好.也就是说,因为当它找到无效字符时,它会立即爆发.
结论:如果你的输入是混合的小,大,错误的字符,错误的计数你最快的方法是使用检查字符串的长度(在.NET中瞬时)和使用有效的正则表达式的组合.
| 归档时间: |
|
| 查看次数: |
1338 次 |
| 最近记录: |