Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用正则表达式重写IsHexString方法_C#_.net_Regex_Hex - Fatal编程技术网

C# 用正则表达式重写IsHexString方法

C# 用正则表达式重写IsHexString方法,c#,.net,regex,hex,C#,.net,Regex,Hex,我得到了一个方法,检查字符串是否是有效的十六进制字符串: 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

我得到了一个方法,检查字符串是否是有效的十六进制字符串

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'));
}
public bool IsHex(字符串值)
{
if(string.IsNullOrEmpty(value)| | value.Length%2!=0)
返回false;
返回
值。子字符串(0,2)=“0x”&&
值。子字符串(2)

.All(c=>(c>='0'&&c='a'&&c='a'&&c因此,基本上您要检查数字是否以
0x
开头,并以0-9和/或a-F的(非空)序列继续。可以很容易地指定为正则表达式:

return RegEx.IsMatch(value, "^0x[0-9A-Fa-f]+$")
我不确定您为什么要执行
value.Length%2!=0
检查……难道“0x1”不是一个有效的十六进制数吗?此外,我的函数在
“0x”
上返回
false
,而您的函数将返回
true
。如果您想更改它,请将
+
(=一个或多个)替换为
*
(=零或多个)在正则表达式中


编辑:既然您已经证明了“偶数”要求的合理性,我建议您使用Abel的正则表达式。如果您这样做,我建议您调用您的方法
IsMsSqlHex
或类似的东西来证明它不符合“通常”的要求十六进制规则。

因此,基本上您希望检查数字是否以
0x
开头,并以0-9和/或a-F(非空)序列继续。可以轻松地指定为正则表达式:

return RegEx.IsMatch(value, "^0x[0-9A-Fa-f]+$")
我不确定您为什么要执行
value.Length%2!=0
检查……难道“0x1”不是一个有效的十六进制数吗?此外,我的函数在
“0x”
上返回
false
,而您的函数将返回
true
。如果您想更改它,请将
+
(=一个或多个)替换为
*
(=零或多个)在正则表达式中


编辑:既然您已经证明了“偶数”要求的合理性,我建议您使用Abel的正则表达式。如果您这样做,我建议您调用您的方法
IsMsSqlHex
或类似的东西来证明它不遵循“通常的”十六进制规则。

更新问题后,适用于您的新正则表达式应该是:

^0x(?[0-9A-Fa-f]{2})+$
其中,我使用
(?:
进行非捕获分组以提高效率。
{2}
表示需要前面表达式中的两个(即两个十六进制字符),
+
表示需要一个或多个十六进制字符。请注意,这不允许将
0x
作为有效值

效率

“ODD”提到了效率问题。我不知道你的要求,所以我认为这是一个比其他任何东西都要多的练习。一个正则表达式将与最小的匹配正则表达式相媲美。例如,在10000个大小为50-5000个字符的变量输入字符串上尝试自己的正则表达式,都是正确的,它运行在1.1秒内。

当我尝试以下正则表达式时:

^0x(?[0-9A-Fa-f]{32})+(?:[0-9A-Fa-f]{2})+$
它的运行速度大约快40%,只需0.67秒。但要小心。了解您的输入意味着知道如何编写高效的正则表达式。例如,如果正则表达式失败,它将进行大量的回溯。如果我的输入字符串有一半的长度不正确,对于相同的输入,运行时间将激增到大约34秒,或3000%(!)

如果大多数输入字符串都很大,则会变得更加棘手。如果99%的输入长度都有效,则所有输入长度都大于4130个字符,只有少数输入长度不有效

^0x(?[0-9A-Fa-f]{4096})+^0x(?[0-9A-Fa-f]{32})+(?:[0-9A-Fa-f]{2})+$
效率更高,时间也更长。但是,如果许多人的
长度%2=0不正确,则由于回溯,这是反效率的

最后,如果大多数字符串满足偶数规则,并且只有部分或多个字符串包含错误字符,则速度会加快:包含错误字符的输入越多,性能越好。这是因为当它发现无效字符时,会立即中断


结论:如果您的输入是大小、错误字符、错误计数的混合输入,您最快的方法是使用组合检查字符串长度(在.NET中为瞬时值)并使用有效的正则表达式。

更新问题后,适用于您的新正则表达式应该是:

^0x(?[0-9A-Fa-f]{2})+$
其中,我使用
(?:
进行非捕获分组以提高效率。
{2}
表示需要前面表达式中的两个(即两个十六进制字符),
+
表示需要一个或多个十六进制字符。请注意,这不允许将
0x
作为有效值

效率

“ODD”提到了效率问题。我不知道你的要求,所以我认为这是一个比其他任何东西都要多的练习。一个正则表达式将与最小的匹配正则表达式相媲美。例如,在10000个大小为50-5000个字符的变量输入字符串上尝试自己的正则表达式,都是正确的,它运行在1.1秒内。

当我尝试以下正则表达式时:

^0x(?[0-9A-Fa-f]{32})+(?:[0-9A-Fa-f]{2})+$
它的运行速度大约快40%,只需0.67秒。但要小心。了解您的输入意味着知道如何编写高效的正则表达式。例如,如果正则表达式失败,它将进行大量的回溯。如果我的输入字符串有一半的长度不正确,对于相同的输入,运行时间将激增到大约34秒,或3000%(!)

如果大多数输入字符串都很大,则会变得更加棘手。如果99%的输入长度都有效,则所有输入长度都大于4130个字符,只有少数输入长度不有效

^0x(?[0-9A-Fa-f]{4096})+^0x(?[0-9A-Fa-f]{32})+(?:[0-9A-Fa-f]{2})+$
效率更高,时间也更长。但是,如果许多人的
长度%2=0不正确,则由于回溯,这是反效率的

最后,如果大多数字符串满足偶数规则,并且只有一些或多个字符串包含错误的字符,则速度会加快:包含错误字符的输入越多,则速度越快
static bool ParseNumber(string value, out int result)
{
    if (string.IsNullOrEmpty(value))
    {
        result = 0;
        return false;
    }

    if (value.StartsWith("0x"))
        return int.TryParse(value.Substring(2), NumberStyles.AllowHexSpecifier, null, out result);
    else
        return int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out result);
}