我正在搜索以下行为的模式:
number1-number2
number1: Can be everything >= 0 and <= int.MaxValue
number2: Can be everything >= number1 and <= int.MaxValue
e.g。
"1-2" => True
"0-0" => True
"10-22" => True
"22-10" => False
"10-10" => True
"a-b" => False
如果我可以直接提取两个int值,那也很好。
答案 0 :(得分:4)
您不能使用正则表达式来比较提取的数字。您需要使用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);
答案 1 :(得分:3)
<强>解决方案强>
可以使用正则表达式对其进行测试 - 但您应该更喜欢代码中的解决方案,因为它会更快。这个正则表达式需要大量的回溯。这个正则表达式的唯一优点是它适用于任意数量的长度。
(?:^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
正整数,包括leeding零。
它不适用于字符。
<强>解释强>
我能够为所有x-y
创建一个匹配x < y
的正则表达式。问题是x <= y
。所以我把问题分成x = y | x < y
。
我们需要处理的是,第一个或两个数字只包含零,但这是微不足道的:
^0+-\d+$
现在案例 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
- 数字比当前y
- 数字慢,我们已完成数字并找到匹配项。如果它慢了我们就不应该匹配。这是通过这种模式完成的:
^
(?>0*) # cut out leeding zeros
(?<prefix>\d*)
.*
-
(?>0*) # cut out leeding zeros
\k<prefix> # both numbers start with the same part
.*
$
现在检查一位数。只有10种可能性[0-9]。它们中的每一个都由一个组捕获:
(?<g0>0)|(?<g1>1)|(?<g2>2)|(?<g3>3)|(?<g4>4)|(?<g5>5)|(?<g6>6)|(?<g7>7)|(?<g8>8)|(?<g9>9)
现在我们可以使用条件来检查当前y
- 位数是否大于当前x
位数。让我们看一下0和1:
(?<g0>0)|(?<g1>1)
:如果0匹配当前x
- 数字,则当前[1-9]
- 数字只有y
。如果只有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
匹配python.exe
的整个正则表达式。
答案 2 :(得分:1)
正则表达式只能用于匹配数字。张贴需要进行比较操作。
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;
会给你一个包含数字的数组