特定字符串的正则表达式

时间:2018-03-10 03:21:51

标签: regex

我正在尝试在xlsx表单中为survey123编写正则表达式代码,以便一次只匹配以下场景之一。该字段可以具有以下之一:

[1-9]{1,3} or 
[0-9]{1,3}/[0-9]{1,3}  or
[0-9]{1,3}/[0-9]{1,3};[0-9]{1,3}/[0-9]{1,3}

第二部分(;[0-9]{1,3}/[0-9]{1,3})重复了不确定的次数。

但是我希望它们所在的场景中需要/;,而不希望它们不在场景中。我的代码不起作用。有人可以帮我解决这个问题吗?

我在在线测试人员https://regexr.com/?32jph中尝试了([0-9]{1,3}\/[0-9]{1,3}\;[0-9]{1,3}\/[0-9]{1,3})|([0-9]{1,3})|([0-9]{1,3}\/[0-9]{1,3}),但我无法将其与2/30/2匹配

不应该有任何前导零。

我正在数鸟。如果鸟类是性别很难区分的鸟类,我只计算鸟类的总数(1-999)。如果可以确定物种性别,那么我记录男性/女性的数量(0/1或2/3)。当我有多个同一物种的性别可以确定时,我会记录男性/女性;男性/女性;男性/女性(0/2; 2/3; 4/0; 1/1)达到该物种的群体数量。当我将这些输入到survey123中时,我希望正则表达式需要正确的格式。

可接受的条目示例如下:

1  
99  
887 
104  
180  
0/99  
300/0  
2/3  
65/3  
1/2;2/0  
1/2;2/0;9/50;3/2;0/1  

1 个答案:

答案 0 :(得分:1)

第一步是让正则表达式识别整数0..999而不带前导零; “单号”示例可能需要1..999变体。

没有前导零意味着:

[1-9][0-9]{0,2}

排除0(因此它涵盖1..999)。单独添加0需要与此等效的东西(有替代方案可以实现相同的结果):

(0|[1-9][0-9]{0,2})

现在你需要将其构建为识别单个数字;由斜杠分隔的一对数字0..999将是:

(0|[1-9][0-9]{0,2})/(0|[1-9][0-9]{0,2})

由分号分隔的这些数字对的列表将是:

(0|[1-9][0-9]{0,2})/(0|[1-9][0-9]{0,2})(;(0|[1-9][0-9]{0,2})/(0|[1-9][0-9]{0,2}))*

因此,整体正则表达式需要:

(0|[1-9][0-9]{0,2})|(0|[1-9][0-9]{0,2})/(0|[1-9][0-9]{0,2})(;(0|[1-9][0-9]{0,2})/(0|[1-9][0-9]{0,2}))*

您可以根据需要添加锚点(例如^$)。如果您的主机语言坚持围绕正则表达式/,则可能需要转义/

转换为Perl并使用锚点,在行的起点和终点允许空格,但不在中间,产生:

#!/usr/bin/env perl

use strict;
use warnings;

my $qr = qr%
            ^ \s* (
            (0|[1-9][0-9]{0,2}) |
            (0|[1-9][0-9]{0,2})/(0|[1-9][0-9]{0,2}) (;(0|[1-9][0-9]{0,2})/(0|[1-9][0-9]{0,2}))*
            ) \s* $
            %x;

while (<>)
{
    chomp;
    if ($_ =~ m/$qr/)
    {
        print "Matches: $_\n";
    }
    else
    {
        print "Failed: $_\n";
    }
}

这是相当冗长,但适度清晰。 qr% … %x表示法编译正则表达式遍布多行,正则表达式中的空格不重要。有许多捕获括号,它们应该是非捕获的,但这是Perl正则表达式的一个特性,不一定在其他地方可用。

给出样本数据:

1  
99  
887  
2/3  
65/3  
1/2;2/0  
1/2;2/0;9/50;3/2;0/1
2x/3
elephant
0
0/0
1/2;3/4;7/8;15/16;31/32;63/64;127/128;255/256;511/512
1000
1234/234
234/1234

输出是:

Matches: 1  
Matches: 99  
Matches: 887  
Matches: 2/3  
Matches: 65/3  
Matches: 1/2;2/0  
Matches: 1/2;2/0;9/50;3/2;0/1
Failed: 2x/3
Failed: elephant
Matches: 0
Matches: 0/0
Matches: 1/2;3/4;7/8;15/16;31/32;63/64;127/128;255/256;511/512
Failed: 1000
Failed: 1234/234
Failed: 234/1234

失败符合我的期望。唯一有争议的线是00/0(您只显示尾随0,而不是前导0)。调整很简单。

Perl允许我使用\d代替[0-9];既然你没有说过你正在使用什么,那么目前尚不清楚这是否适合你。