代码之家  ›  专栏  ›  技术社区  ›  Blackbam

PHP:preg\u match\u all()-如何正确查找正则表达式中出现的所有子字符串或分隔的子字符串?

  •  0
  • Blackbam  · 技术社区  · 6 年前

    我的任务是在一个只有数字的字符串中找到所有连续的数字。然而,我不是在寻找一个更好的正则表达式来实现这一点,而是寻找一个匹配子字符串的正确正则表达式。

    我就是这样构建正则表达式的:

    $regex = "";
    
    for($i=0;$i<10;$i++) {
        $str = "";
        for($a=0;$a<10;$a++) {
            if($a > $i) {
                $str .= $a;
                if(strlen($str)>1) {
                  $regex .= "|".$str."";
                }
            }
        }
    }
    
    $myregex = "/".ltrim($regex,"|")."/";
    echo $myregex;
    

    然后我会:

    $literal = '234121678941251236544567812122345678';
    $matches = [];
    preg_match_all($myregex,$literal,$matches);
    var_dump($matches);
    

    结果:

    array(1) {
      [0]=>
      array(13) {
        [0]=>
        string(2) "23"
        [1]=>
        string(2) "12"
        [2]=>
        string(2) "67"
        [3]=>
        string(2) "89"
        [4]=>
        string(2) "12"
        [5]=>
        string(2) "12"
        [6]=>
        string(2) "45"
        [7]=>
        string(2) "67"
        [8]=>
        string(2) "12"
        [9]=>
        string(2) "12"
        [10]=>
        string(2) "23"
        [11]=>
        string(2) "45"
        [12]=>
        string(2) "67"
      }
    }
    

    全部的 匹配(抱歉,仍然有点正则表达式noob)。如何修改正则表达式?

    1 回复  |  直到 6 年前
        1
  •  2
  •   ArtisticPhoenix    6 年前

    正则表达式的顺序很重要。我不确定这样做是否完全解决了这个问题这种方法可能有根本性的缺陷,但你可以试试这个:

    $regex = [];
    
    for($i=0;$i<10;$i++) {
        $str = "";
        for($a=0;$a<10;$a++) {
            if($a > $i) {
                $str .= $a;
                if(strlen($str)>1) {
                  $regex[] = $str;
                }
            }
        }
    }
    
    usort($regex, function($a,$b){
        return strlen($b) <=> strlen($a);
    });
    
    $myregex = '/'.implode('|', $regex).'/';
    

    它所做的是将数字序列做成一个数组,然后按长度对它们排序,并首先排列最长的序列。最终结果是(匹配后)

    array(1) {
      [0]=>
      array(9) {
        [0]=>
        string(3) "234"
        [1]=>
        string(2) "12"
        [2]=>
        string(4) "6789"
        [3]=>
        string(2) "12"
        [4]=>
        string(3) "123"
        [5]=>
        string(5) "45678"
        [6]=>
        string(2) "12"
        [7]=>
        string(2) "12"
        [8]=>
        string(7) "2345678"
      }
    }
    

    还要注意宇宙飞船操作员 <=>

    希望有帮助。

    Sandbox

    23 234 2345 2345607 例如。然而,如果它匹配一个长序列,那么逻辑上,它只能合理地匹配一个较短的序列。所以你可以删掉右边的数字,直到长度为2,然后得到匹配的数字。