我正在搜索以下行为的模式:
number1-number2
number1: Can be everything >= 0 and <= int.MaxValue
number2: Can be everything >= number1 and <= int.MaxValue例如:
"1-2" => True
"0-0" => True
"10-22" => True
"22-10" => False
"10-10" => True
"a-b" => False如果我能直接提取两个int值,那就更好了。
发布于 2015-09-16 19:28:49
您不能使用正则表达式来比较提取的数字。您需要使用int.TryParse解析这些值,并实现其他检查以获得所需的内容。
假设范围中只有个整数正数,下面是String.Split和int.TryParse方法:
private bool CheckMyRange(string number_range, ref int n1, ref int n2)
{
var rng = number_range.Split('-');
if (rng.GetLength(0) != 2)
return false;
if (!int.TryParse(rng[0], out n1))
return false;
if (!int.TryParse(rng[1], out n2))
return false;
if (n1 >= 0 && n1 <= int.MaxValue)
if (n2 >= n1 && n2 <= int.MaxValue)
return true;
return false;
}并将其命名为
int n1 = -1;
int n2 = -1;
bool result = CheckMyRange("1-2", ref n1, ref n2);发布于 2015-09-16 20:03:34
解决方案
可以使用正则表达式测试它-但您应该首选代码解决方案,因为它会快得多。这个正则表达式需要很多回溯。这个正则表达式的唯一优点是它可以处理任意长度的数字。
(?:^0+-\d+$)
|
(?:^(?>0*)(?<number>\d+)-(?>0*)\k<number>$)
|
(?:
(?:^(?>0*)(?<length>\d)+-(?>0*)(?<-length>\d)*(?(length)(?!))\d+$)
|
(
(?=^(?>0*)(?<o>\d)+-(?>0*)(?<-o>\d)*(?(o)(?!))$)
^
(?>0*)
(?<prefix>\d*)
(?:(?<g0>0)|(?<g1>1)|(?<g2>2)|(?<g3>3)|(?<g4>4)|(?<g5>5)|(?<g6>6)|(?<g7>7)|(?<g8>8)|(?<g9>9))
\d*
-
(?>0*)
\k<prefix>
(?(g0)[1-9]|(?(g1)[2-9]|(?(g2)[3-9]|(?(g3)[4-9]|(?(g4)[5-9]|(?(g5)[6-9]|(?(g6)[7-9]|(?(g7)[89]|(?(g8)9|(?!))))))))))
\d*
$
)
)对于每个x-y,其中x <= y表示正整数,包括列数为零,都会匹配。
DEMO
它不适用于字符。
说明
我能够为所有的x < y创建一个匹配x-y的正则表达式。问题是x <= y。所以我把这个问题分给了x = y | x < y。
我们需要处理第一个或两个数字确实只包含零,但这是微不足道的:
^0+-\d+$现在是case x = y
^(?>0*)(?<number>\d+)-(?>0*)\k<number>$棘手的部分是x < y。
如果
x的字符长度比y短,则x小于y (原子基团捕获列数为零的零):^(?>0*)(?<length>\d)+-(?>0*)(?<-length>\d)*(?(length)(?!))\d+
第一组通过每个数字一次捕获来捕获整个数字。在分隔符之后,平衡组定义将清除捕获堆栈并强制至少多一个数字。
为了确保这两个数字具有相同的长度,我从断言后面的正面观察开始,以确保它与我在步骤1中测试较长数字的方式相同:
(?=^(?>0*)(?<o>\d)+-(?>0*)(?<-o>\d)*(?(o)(?!))$)
之后,算法就很简单了。从头开始。如果当前数字相等,则转到下一个数字。如果当前的x-digit比当前的y-digit慢,我们就完成了,并且找到了匹配项。如果它更慢,我们就不应该匹配。这是由该模式完成的:
^ (?>0*) #去掉离线零(?\d*) .* - (?>0*) #去掉离线零\k #两个数字都以相同的部分.* $开头
现在是一位数的检查。只有10种可能性0-9。它们中的每一个都被一个组捕获:
(?<g0>0)|(?<g1>1)|(?<g2>2)|(?<g3>3)|(?<g4>4)|(?<g5>5)|(?<g6>6)|(?<g7>7)|(?<g8>8)|(?<g9>9)
现在我们可以使用条件来检查当前的y-digit是否大于当前的x-digit。让我们展示一下0和1:
(?<g0>0)|(?<g1>1):如果0与当前x-digit匹配,则当前y-digit只有[1-9]。如果1匹配,则只能使用[2-9]。这可以在以下条件下使用:
(?(g0)[1-9]|...)意味着如果g0有一个捕获,[1-9]必须匹配,否则其余的也必须匹配。这两者结合在一起可以:
(?(g0)[1-9]|(?(g1)[2-9]|(?(g2)[3-9]|(?(g3)[4-9]|(?(g4)[5-9]|(?(g5)[6-9]|(?(g6)[7-9]|(?(g7)[89]|(?(g8)9|(?!))))))))))
最后一个技巧是,所有组g[0-8]都没有匹配,只有g9可用,没有更大的数字,匹配应该失败(?!).
这一切都被合并到与所有x <= y的x-y匹配的整个正则表达式中。
发布于 2015-09-16 19:16:52
正则表达式只能用于匹配数字。发布需要完成的比较操作。
string num="number1-number2";//where (number1 & number2)=numeric val
MatchCollection stringVal= Regex.Matches(num,@"\d+");
int num1=Convert.ToInt32(stringVal[0].Value);
int num2=Convert.ToInt32(stringVal[1].Value);
if(num1>=0 && num1<=int.MaxValue && num2>=num1 && num2<=int.MaxValue)
return true;
else
return false;将为您提供一个包含数字的数组
https://stackoverflow.com/questions/32606905
复制相似问题