phppreg-match-all

preg_match_all() returns only the last matches from a single row, but all matches from a multi-row string


I try to find all occurrences of a substring in text, using the preg_match_all() function:

<?php
    $str = '<p>this <a href="https://api.slack.com/apps/" target="_blank">link</a> and <a href="https://www.google.com" target="_blank">link 2</a></p>';

    $reg = '/<a.*href="([^"]+)"[^>]+>(.+)<\/a>/';

    preg_match_all($reg, $str, $m);

    print_r($m);

But the above code returns only the last link: run PHP online

When I split the source text into rows, the same code returns all matches:

<?php
    $str = '<p>this <a href="https://api.slack.com/apps/" target="_blank">link</a> and
    the <a href="https://www.google.com" target="_blank">link 2</a></p>';

    $reg = '/<a.*href="([^"]+)"[^>]+>(.+)<\/a>/';

    preg_match_all($reg, $str, $m);

    print_r($m);

PHP sandbox here


Solution

  • The problem is your regular expression. You can limit the characters:

    /<a\s*href="([^"]+)"[^>]+>([^<]+)<\/a>/
    

    Or use lazy matching:

    /<a.*?href="([^"]+)"[^>]+>(.+?)<\/a>/