正则表达式模式number1到number2

时间:2015-09-16 11:07:57

标签: c# regex string

我正在搜索以下行为的模式:

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值,那也很好。

3 个答案:

答案 0 :(得分:4)

您不能使用正则表达式来比较提取的数字。您需要使用int.TryParse解析值并执行其他检查以获得所需内容。

假设您在范围中只有 整数正数 ,这里采用String.Splitint.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零。

DEMO

它不适用于字符。

<强>解释

我能够为所有x-y创建一个匹配x < y的正则表达式。问题是x <= y。所以我把问题分成x = y | x < y

我们需要处理的是,第一个或两个数字只包含零,但这是微不足道的:

^0+-\d+$

现在案例 x = y

^(?>0*)(?<number>\d+)-(?>0*)\k<number>$

棘手的部分是x < y

  1. x小于y,如果x的字符长度比y短(原子组捕获的是零):

    ^(?>0*)(?<length>\d)+-(?>0*)(?<-length>\d)*(?(length)(?!))\d+

    第一组捕获每个数字一次捕获的整数。在分隔符之后,平衡组定义清除捕获堆栈并强制至少再增加一个数字。

  2. 这两个数字的长度相同(如果第一个数字越长,它也越大且不匹配)。

    为了确保两个数字的长度相同,我开始以断言后面的正面看法确保它与我在步骤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

  3. 这一切已合并到与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;

会给你一个包含数字的数组