我得到一个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上包含测试和预期值的完整示例源代码。
答案 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!)
((?:^|\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*)
- 第二组(数字)。