使用两个固定长度的数字组正则表达式并删除其前导零

时间:2012-09-07 18:20:05

标签: python regex

我得到一个15位的输入字符串,即001230123456789。 它有两个数字 - 第一个是00123(最小1个非零数字,最多5个数字),第二个是0123456789(最小100000000,最多10位数) 。捕获的输出(这些数字)不应包含前导零。

更简单,也许是唯一正确的方法(在Python中)是数组切片和lstrip():

input = "001230123456789"
output = [(input[:5].lstrip('0'), input[5:].lstrip('0'))]
# ('123', '123456789')

但我有一个任务是用正则表达式做同样的事情。

我不得不留下zome零,无论我是否尝试过贪婪的选择。 我结束了那个:0{0,4}([1-9]\d{0,4})0?([1-9]\d{8,9}) 它通过了3/6的测试:

000010111111111 -    ('10', '111111111')     (should be ('1', '111111111'))
116402151672479 - OK ('11640', '2151672479')
006421651672479 -    ('6421', '651672479')   (should be ('642', '1651672479'))
712120751672479 - OK ('71212', '751672479')
712121551672479 - OK ('71212', '1551672479')
006400351672479 -    ('6400', '351672479')   (should be ('640', '351672479'))

有没有办法只使用正则表达式?

pastie.org上包含测试和预期值的完整示例源代码。

4 个答案:

答案 0 :(得分:4)

你走了。

    /^0*(\d{1,5})(?<=.{5})(?<!00000)(?!00)(?=\d{10}$)0*(.+)/
      | |        |        |         |     |          | |
      | |        |        |         |     |          | capture 2nd number
      | |        |        |         |     |          |
      | |        |        |         |     |          chomp leading zeroes
      | |        |        |         |     |
      | |        |        |         |     assert there're 10 digits ahead
      | |        |        |         |
      | |        |        |         assert second part at least 100000000
      | |        |        |
      | |        |        make sure first part at least one nonzero digit
      | |        |
      | |        assert there are 5 chars behind (already tested numeric)
      | |
      | capture 1st number (don't worry; the assertions will fix this up)
      |
      chomp leading zeroes (i'm going to line up these comments damn it!)

此处a Rubular demo

(?:^|\s)(?:\s|$)仅用于演示目的。)

以下是结果:

    000010111111111             -->     1       111111111
    116402151672479             -->     11640   2151672479
    006421651672479             -->     642     1651672479
    712120751672479             -->     71212   751672479
    712121551672479             -->     71212   1551672479
    006400351672479             -->     640     351672479

    # not enough digits        
    71212155167247              -->     no match

    # too many digits          
    7121215516724798            -->     no match           

    # first part == 0          
    000001551672479             -->     no match            

    # second part < 100,000,000
    712120098765479             -->     no match

答案 1 :(得分:3)

我对python并不是很熟悉,但下面的解决方案(perl)会完全按照你的意愿行事;虽然很难看。

use strict;

my @test = qw/000010111111111 116402151672479 006421651672479 712120751672479 712121551672479 006400351672479/;

foreach(@test){
    /^(?|([1-9]\d{4})|0([1-9]\d{3})|00([1-9]\d{2})|000([1-9]\d)|0000([1-9]))(?|0([1-9]\d{8})|([1-9]\d{9}))/;
    print "$_: ($1, $2)\n";
}

exit 0;

快速查看python re页面,我没有明确地看到(?|...),但确实有(?:...)。在这种情况下,你会获得一系列匹配,只有两个非空白条目 - 这将是你的答案。

答案 2 :(得分:2)

试试这个Python正则表达式:

0{0,4}(\d+)(?<=^\d{5})0{0,9}(\d+)
|     |    |          |     |
|     |    |          |     Second number without leading zeros
|     |    |          Up to 9 leading zeros of second number
|     |    Must be preceded by start of string and 5 digits
|     First number without leading zeros
Up to 4 leading zeros of first number

答案 3 :(得分:2)

这是我的解决方案:

re.search(r'([1-9]\d*)(?=\d{10})0*([1-9]\d*)', "0064000351672479").groups()
# ('640', '351672479')

故障:

  • ([1-9]\d*) - 第一组,必须从1-9开始,
  • (?=\d{10}) - 向前看断我们有10个数字,
  • 0* - chomp领导人从第二个号码开始零,
  • ([1-9]\d*) - 第二组(数字)。