Search code examples
phpregexpreg-match

regex help about multiple string with ,


I have a string of tfa_2,tfa_3,tfa_4 and I have a regex of /^tfa_\d+/

How can I make it select all the tfa_1...tfa_999 and disregard the comma?

Thanks.


Solution

  • Assuming the input contains the exact format ^tfa_\d+(,tfa_\d+)*$ and no limit on the number after tfa_

    The simplest solution is to use explode:

    $tokens = explode(",", "tfa_2,tfa_3,tfa_4");
    

    You can also use preg_split or preg_match, but they are overkill under this assumption:

    $tokens = preg_split('/,/', "tfa_2,tfa_3,tfa_4");
    
    $retcode = preg_match_all('/tfa_\d+/', "tfa_2,tfa_3,tfa_4", $tokens);
    

    Assuming the input contains the exact format ^[^,]+(,[^,]+)*$, no quoted token, and no limit on the number after tfa_

    You need to assert that tfa_\d+ is not preceded or suceeded by a non-separator (non-comma character) to prevent htfa_345, tfa_456xxx, -tfa_34 from being considered a match:

    $retcode = preg_match_all('/(?<![^,])tfa_\d+(?![^,])/', "tfa_2,tfa_3,tfa_4,htfa_345,tfa_456xxx,-tfa_34", $tokens);
    

    Alternate solution, by explode the string along , and use array_filter to filter out unwanted fields:

    $fields = explode(",", "tfa_2,tfa_3,tfa_4,htfa_345,tfa_456xxx,-tfa_34");
    $tokens = array_filter($fields, function ($v) {
        return preg_match('/^tfa_\d+$/', $v) == 1;
    });
    

    Assuming the input contains the exact format ^[^,]+(,[^,]+)*$, no quoted token, and the number after tfa_ can only be 1 to 999

    Just modify the regex a bit to limit the number ([1-9]\d{0,2}):

    $retcode = preg_match_all('/(?<![^,])tfa_[1-9]\d{0,2}(?![^,])/', "tfa_2,tfa_3,tfa_4456,htfa_345,tfa_456xxx,-tfa_34", $tokens);
    

    Similar modification for explode + array_filter solution:

    $fields = explode(",", "tfa_2,tfa_3,tfa_4456,htfa_345,tfa_456xxx,-tfa_34");
    $tokens = array_filter($fields, function ($v) {
        return preg_match('/^tfa_[1-9]\d{0,2}$/', $v) == 1;
    });