【问题标题】:Perl Regular expression to match string contains alphabets/digits/dotPerl 正则表达式匹配字符串包含字母/数字/点
【发布时间】:2020-01-11 07:04:42
【问题描述】:

我正在尝试匹配包含字母数字、数字和点的字符串。

  • 以字母 [a-z|A-Z] 开头,后跟用点分隔的数字 在 [1.2.3.5] 之间并且仅以数字结尾。

我尝试匹配的一些示例:

my @patternsTomatch = (
 'SAN100.25.36.2',   # Valid string 
, 'DF1.2.3.5',       # Valid string
, 'BADPATTERN',      # In-Valid string
, '12BADPATTERN',    # In-Valid string
, '.DF1.2.3.5',       # In-Valid string
, 'SAN100.25.36.2.'  # In-Valid string
);

foreach my $pattern (@patternsTomatch) {
   if ( $pattern =~ /^([a-z|A-Z]+)(\d+\.)(.*)$/ ) { print " $pattern \n"; }
}

但上述尝试无法正常工作?

另外,需要一个正则表达式来匹配固定格式字符串 XC1.2.3.4_25 在单独的条件下。

  • 以字母 [a-z|A-Z] 开头,后跟用点分隔的数字 在 [1.2.3.5] 之间,后跟只有一个下划线并以 only 结尾 数字。

谢谢。

【问题讨论】:

    标签: regex perl


    【解决方案1】:

    您可能首先匹配 1+ 个字符 [A-Za-z]+(请注意,您不需要字符类中的管道),然后重复匹配的数字,中间有一个点:

    ^[A-Za-z]+\d+(?:\.\d+)+$
    

    regex demo


    要匹配末尾的下划线和数字,您可以在断言字符串末尾之前在模式末尾添加匹配下划线和 1+ 数字:

    ^[A-Za-z]+\d+(?:\.\d+)+_\d+$
    

    Regex demo

    【讨论】:

    • 谢谢...解决了我的问题。任何机会你也可以帮我匹配字符串 XC1.2.3.4_25!
    • 我想将 XC1.2.3.4_25 匹配为不匹配 XC1.2.3.4 或 SAN100.25.36.2 的单独表达式
    • @LittleMagnolia 然后你可以在表达式的末尾匹配它而不让它成为可选的regex101.com/r/fvsahx/1
    • 非常感谢您的快速回复。解决了我的问题
    【解决方案2】:

    我想你想要更多这样的东西:

    my @candidates = (
      'SAN100.25.36.2',   # Valid string
      'DF1.2.3.5',        # Valid string
      'BADPATTERN',       # In-Valid string
      '12BADPATTERN',     # In-Valid string
      '.DF1.2.3.5',       # In-Valid string
      'SAN100.25.36.2.'   # In-Valid string
    );
    
    # store the pattern in a variable to get it out of the way 
    # of the logic
    my $pattern = qr/
        \A          # beginning of string
        [a-z]+      # latin letters, case insensitive
        \d+         # digits
        (?:         # groups of . and digits
            \.
            \d+
        )+
        (?:         # optional _ digits at end (or leave this group out)
            _
            \d+
        )?
        \z          # end of string
        /ix;        # /i - case insenstive  /x - expanded format
    
    foreach my $candidate ( @candidates ) {
       if( $candidate =~ $pattern ) {
         print "$candidate matched\n";
         }
       else {
         print "$candidate missed\n";
         }
    }
    

    【讨论】:

    • 当我建议将 _\d+ 部分设为可选 I want to match XC1.2.3.4_25 as separate expression that doesn't match XC1.2.3.4 or SAN100.25.36.2 时,OP 添加了此评论,这就是我添加 2 种模式的原因。
    • 这就是为什么我留下评论“(或离开这个小组)”
    【解决方案3】:

    使代码尽可能简单

    use strict;
    use warnings;
    
    use feature 'say';
    
    my @match = grep { chomp; /^[a-z]+\d+(:?\.\d+)+(:?_\d+)?$/i } <DATA>;
    
    map{ say } @match;
    
    __DATA__
    SAN100.25.36.2
    DF1.2.3.5
    BADPATTERN
    12BADPATTERN
    .DF1.2.3.5
    SAN100.25.36.2.
    XC1.2.3.4_25
    

    输出

    SAN100.25.36.2
    DF1.2.3.5
    XC1.2.3.4_25
    

    【讨论】:

    • 我已经建议了可选的_\d+部分,但是OP的响应是I want to match XC1.2.3.4_25 as separate expression that doesn't match XC1.2.3.4 or SAN100.25.36.2 顺便说一句,你为什么要匹配一个可选的冒号:?
    • @第四只鸟——不清楚为什么 OP 提到了单独的模式,当它可以在一个中完成时。我为这两种情况制作了一种模式_\d+ 可以出现或不出现。我们无法阅读 OP 的思想来理解他们遵循的想法。很多时候,问题的定义不是很明确,我们可以做出很多假设。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-21
    • 1970-01-01
    • 2016-09-01
    • 1970-01-01
    • 2019-06-26
    • 1970-01-01
    • 2015-02-26
    相关资源
    最近更新 更多