在Perl中,如何检测字符串是否多次出现两位数?

时间:2009-07-22 10:58:14

标签: regex perl repeat

我想匹配110110但不匹配10110.这意味着至少两次重复两个相同的连续数字。任何正则表达式?

应符合:110110,123445446,12344544644

不匹配:10110,123445

6 个答案:

答案 0 :(得分:9)

/(\d)\1.*\1\1/

这匹配一个带有2个双数实例的字符串,即11011但不是10011

\d匹配任何数字 \1匹配第一个匹配有效加倍第一个条目

这也将匹配1111.如果在更改。*到。+

之间需要有其他字符

哦,这看起来更整洁

((\d)\2).*\1

如果你想找到不匹配的值,但必须有2组双打,那么你只需要再次添加第一部分,如

((\d)\2).*((\d)\4)

包围将意味着1美元和3美元将包含两位数,$ 2和$ 4包含单个数字(然后加倍)。

11233

$1=11
$2=1
$3=33
$4=3

答案 1 :(得分:7)

如果我理解正确,你的正则表达式将是:

m{
  (\d)\1            # First repeated pair
  .*                # Anything in between
  (\d)\2            # Second repeated pair
}x

例如:

for my $x (qw(110110 123445446 12344544644 10110 123445)) {
    my $m = $x =~ m{(\d)\1.*(\d)\2} ? "matches" : "does not match";
    printf "%-11s : %s\n", $x, $m;
}
110110      : matches
123445446   : matches
12344544644 : matches
10110       : does not match
123445      : does not match

答案 2 :(得分:3)

如果您正在谈论所有数字,则可以这样做:

00.*00|11.*11|22.*22|33.*33|44.*44|55.*55|66.*66|77.*77|88.*88|99.*99

只有9个不同的模式或“在一起”,每个模式至少检查两次所需的2位数模式。

使用Perls更高级的RE,您可以将以下两个连续数字用于两次:

(\d)\1.*\1\1

或者,正如你的一条评论所指出的那样,两个连续的数字在两个连续的数字之后,可能不一样:

(\d)\1.*(\d)\2

答案 3 :(得分:0)

如果我已正确理解你的问题,那么根据regexbuddy(设置为使用perl语法),这将匹配110110但不匹配10110:

(1{2})0\10

以下内容更为通用,将匹配以后在字符串中重复两位相等数字的字符串。

(\d{2})\d+\1\d*

以上将与以下示例相符:

110110 110011 112345611 2200022345

最后,要在字符串中找到两组双位数而你不在乎它们的位置,试试这个:

\d*?(\d{2})\d+?\1\d*

这将匹配上面的示例加上这一个:

12345501355789

上面例子中的两组双5匹配。

<强> [更新] 刚刚看到你需要匹配一个字符串和两个不同的两位数字,试试这个:

\d*?(\d)\1\d*?(\d)\2\d*

这将匹配以下字符串:

12342202345567
12342202342267

请注意,22和55会导致第一个字符串匹配,而22对会导致第二个字符串匹配。

答案 4 :(得分:0)

没有理由在一个正则表达式中执行所有操作...您可以使用Perl的其余部分:

#!/usr/bin/perl -l

use strict;
use warnings;

my @strings = qw( 11233 110110 10110 123445 123445446 12344544644 );

print if is_wanted($_) for @strings;

sub is_wanted {
    my ($s) = @_;
    my @matches = $s =~ /(?<group>(?<first>[0-9])\k<first>)/g;
    return 1 < @matches / 2;
}

__END__

答案 5 :(得分:0)

取决于您的数据如何,这是一种最小的正则表达方式。

while(<DATA>){
    chomp;
    @s = split/\s+/;
    foreach my $i (@s){
        if( $i =~ /123445/ && length($i) ne 6){
            print $_."\n";
        }
    }
}

__DATA__
  This is a line
  blah 123445446 blah
  blah blah 12344544644 blah
  .... 123445 ....
  this is last line