代码之家  ›  专栏  ›  技术社区  ›  CSchulz cL83

用regex正确分组

  •  0
  • CSchulz cL83  · 技术社区  · 15 年前

    我有一个包含命令列表的regex。但我不知道它后面是什么样的参数,所以它可以是一个字符串、一个数字或者什么都不是。
    可能我不知道命令。

    在我的第一个版本中没有任何字符串,所以 (abc|def|[a-z]+)([0-9]*) 工作良好。但现在我也要允许使用字符串。 (abc|def|[a-z]+)([0-9]*|[a-z]*) 不起作用。

    字符串1:abc2def20ghi20
    字符串2:ABCDEF20GHI20
    字符串3:DDEF2D0GHI20ABCD D

    字符串1:
    regex 1示例: ABC20***DEF20***GHI20型
    regex 2示例: ABC20***DEF20***GHI20型

    字符串2:
    regex 1示例: ABC公司***DDDEF20公司***GHI20公司
    regex 2示例: ABC公司***DDDEF20公司***GHI20公司

    我想得到以下结果: ABC20***DEF20***GHI20型 ABCD D***def20***ghi20

    谢谢你的帮助。

    2 回复  |  直到 15 年前
        1
  •  1
  •   reko_t    15 年前

    根据你最新的评论,也许这会给你带来好处:

    (abc|def)(\d+|(?:(?!(?1))[a-z])+)?|((?:(?!(?1))[a-z])+)((?2))?
    

    编辑。哎呀,是想编辑我以前的答案,而不是发布新的答案。

    测试用例:

    <?php
    
    $r = '#(abc|def)(\d+|(?:(?!(?1))[a-z])+)?|((?:(?!(?1))[a-z])+)((?2))?#';
    $s1 = 'abc20def20ghi20';
    $s2 = 'abcdddef20ghi20';
    $s3 = 'abcdddef2d0ghi20abcdd';
    
    preg_match_all($r, $s1, $m1);
    preg_match_all($r, $s2, $m2);
    preg_match_all($r, $s3, $m3);
    var_dump($m1[0], $m2[0], $m3[0]);
    

    输出:

    array(3) {
      [0]=>
      string(5) "abc20"
      [1]=>
      string(5) "def20"
      [2]=>
      string(5) "ghi20"
    }
    array(3) {
      [0]=>
      string(5) "abcdd"
      [1]=>
      string(5) "def20"
      [2]=>
      string(5) "ghi20"
    }
    array(5) {
      [0]=>
      string(5) "abcdd"
      [1]=>
      string(4) "def2"
      [2]=>
      string(2) "d0"
      [3]=>
      string(5) "ghi20"
      [4]=>
      string(5) "abcdd"
    }
    

    如您所见,它正确地捕获了两个字符串中的所有部分。

        2
  •  0
  •   reko_t    15 年前

    是否总是要捕获长度为5的字符串?如果是这样,您可以这样做:

    ([a-z]{3})([0-9a-z]{2})
    

    如果不是,也许您可以澄清“abcdd”和“def20”之间“剪切”字符串的具体标准是什么?