首页 > 解决方案 > 匹配给定模式并以可选数字结尾的正则表达式

问题描述

我一直在尝试使用正则表达式来匹配和提取 URL 的一部分。URL 模式如下所示:

http://domain.abcdef/xyz/fe/fi/fo5/fu2m/123/

我打算捕获以下群体:

  1. 匹配和捕获xyz(可选,但具体值)
  2. 匹配和捕获fe/fi/fo5/fu2m(必须存在,任意值)
  3. 匹配和捕获123(可选数值,必须出现在末尾)

以下是我尝试过的表达式和遇到的问题:

字符串1:http://domain.abcdef/xyz/fe/fi/fo5/fu2m/123/

字符串2:http://domain.abcdef/xyz/fe/fi/fo5/fu2m/

^(?:https?:\/\/)?(?:[\da-z\.-]+)\.(?:[a-z\.]{2,6})(?:\/(xyz))?\/([\/\w]+)+(?:\/([\d]+))\/$

我的问题是如何在所有场景中捕获组 1、2 和 3,包括。string1 和 string2(注意:我使用的是 PHP 的preg_match函数)

标签: phpregex

解决方案


使用修改后的 URL 验证器。

'~^(?!mailto:)(?:(?:https?|ftp)://)?(?:\S+(?::\S*)?@)?(?:(?:(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))|localhost)(?::\d{2,5})?(?:/(xyz))?((?:/(?!\d+/?$)[^/]*)+)(?:/(\d+))?/?\s*$~'

第 1 组是可选的xyz
第 2 组是必需的 中间
第 3 组是可选的数字在末尾

可读版本

 ^ 
 (?! mailto: )
 (?:
      (?: https? | ftp )
      ://
 )?
 (?:
      \S+ 
      (?: : \S* )?
      @
 )?
 (?:
      (?:
           (?:
                [1-9] \d? 
             |  1 \d\d 
             |  2 [01] \d 
             |  22 [0-3] 
           )
           (?:
                \.
                (?: 1? \d{1,2} | 2 [0-4] \d | 25 [0-5] )
           ){2}
           (?:
                \.
                (?:
                     [1-9] \d? 
                  |  1 \d\d 
                  |  2 [0-4] \d 
                  |  25 [0-4] 
                )
           )
        |  (?:
                (?: [a-z\u00a1-\uffff0-9]+ -? )*
                [a-z\u00a1-\uffff0-9]+ 
           )
           (?:
                \.
                (?: [a-z\u00a1-\uffff0-9]+ -? )*
                [a-z\u00a1-\uffff0-9]+ 
           )*
           (?:
                \.
                (?: [a-z\u00a1-\uffff]{2,} )
           )
      )
   |  localhost
 )
 (?: : \d{2,5} )?
 (?:
      / 
      ( xyz )  # Optional specific value
 )?
 (  # Must exist, arbitrary value
      (?:
           /
           (?! \d+ /? $ )  # Not a numeric value at the end
           [^/]* 
      )+
 )
 (?:
      / 
      ( \d+ )  # Optional numeric value, which must appear at the end
 )?
 /?
 \s* 
 $   

输出

 **  Grp 0 -  ( pos 0 : len 46 ) 
http://domain.abcdef/xyz/fe/fi/fo5/fu2m/123/

 **  Grp 1 -  ( pos 21 : len 3 ) 
xyz  
 **  Grp 2 -  ( pos 24 : len 15 ) 
/fe/fi/fo5/fu2m  
 **  Grp 3 -  ( pos 40 : len 3 ) 
123  



 **  Grp 0 -  ( pos 48 : len 42 ) 
http://domain.abcdef/xyz/fe/fi/fo5/fu2m/

 **  Grp 1 -  ( pos 69 : len 3 ) 
xyz  
 **  Grp 2 -  ( pos 72 : len 18 ) 
/fe/fi/fo5/fu2m/

 **  Grp 3 -  NULL 

推荐阅读