代码之家  ›  专栏  ›  技术社区  ›  Christian Studer delphist

如何用一个正则表达式查找多个匹配项?

  •  0
  • Christian Studer delphist  · 技术社区  · 14 年前

    我有以下字符串:

    response: id="1" message="whatever" attribute="none" world="hello"
    

    属性的顺序是随机的。可能还有许多其他属性。

    是否有一种方法可以在一个正则表达式中获取id、message和world属性,而不是逐个应用以下三个属性?

    / message="(.*?)"/
    / world="(.*?)"/
    / id="(.*?)"/
    
    4 回复  |  直到 14 年前
        1
  •  2
  •   gnarf    14 年前

    您可以通过使用三个具有 .* 在他们前面:

    <?php
    $re = '/(?=.* message="(.*?)")(?=.* world="(.*?)")(?=.* id="(.*?)")/';
    
    $string = '<response id="1" message="whatever" attribute="none" world="hello" />';
    
    preg_match($re, $string, $matches);
    var_dump($matches);
    

    输出:

    array(4) {
      [0]=>
      string(0) ""
      [1]=>
      string(8) "whatever"
      [2]=>
      string(5) "hello"
      [3]=>
      string(1) "1"
    }
    

    当然,如果这3个参数中的任何一个丢失,此模式将失败(这可能对您也有帮助…)。如果您希望它们是可选的,那么可以进一步将lookahead的内部包装为非捕获组,并使其成为可选的 (?:....)? (此示例使“world”参数可选)

    /(?=.* message="(.*?)")(?=(?:.* world="(.*?)")?)(?=.* id="(.*?)")/
    
        2
  •  0
  •   Daniel DiPaolo    14 年前

    如果您正在使用 preg_match ,然后还有一个可选的第三个参数,它将存储所有正则表达式 (括号内的任何内容,基本上)以及完全匹配。

    因此,使用整个元素作为一个正则表达式,然后第二、第三和第四个元素将是 message , world id 分别(第一个是匹配的整个字符串。

        3
  •  0
  •   gnarf    14 年前

    我不是雷鬼,所以这可能是错的。如果是,不要投反对票()只要让我知道,我会删除它!-D

    你能不能把这些短语放在一起搭配一下?

    / (message|world|id)="(.*?)"/

        4
  •  0
  •   Svend    14 年前

    下面是我能想到的最好的一个。它应该捕获每个点上匹配的实际属性及其值,并允许在中间插入任何其他属性。不过,这并不完全正确,您最好使用“真正的”解析器。

    /((message|attribute|world)="([^"]*)").*?((message|attribute|world)="([^"]*)").*?((?:message|attribute|world)="([^"]*)")/