PHP regex groups captures

51,887

Solution 1

This is not the job for the regexp. Match against \[([^\]]*)\], then split the first capture by the " - ".

<?php                                                                       
  $str = "[abc - def - ghi - jkl]";
  preg_match('/\[([^\]]*)\]/', $str, $re);
  $strs = split(' - ', $re[1]);
  print_r($strs);
?>

Solution 2

Assuming the tokens in your sample string never contain spaces, and are alphanumeric:

<?php
    $pattern = "/([\w|\d])+/";
    $string = "[abc - 123 - def - 456 - ghi - 789 - jkl]";
    preg_match_all($pattern, $string, $matches);
    print_r($matches[0]);
?>

Output:

Array
(
    [0] => abc
    [1] => 123
    [2] => def
    [3] => 456
    [4] => ghi
    [5] => 789
    [6] => jkl
)

Solution 3

SPL preg_match_all will return regex groups starting on index 1 of the $matches variable. If you want to get only the second group you can use $matches[2] for example.

Syntax:

$matches = array(); 
preg_match_all(\
    '/(He)\w+ (\w+)/', 
    "Hello world\n Hello Sunshine", 
    $matches
); 
var_dump($matches);

Result:

array(3) {
  [0] =>
  array(2) {
    [0] =>
    string(11) "Hello world"
    [1] =>
    string(14) "Hello Sunshine"
  }
  [1] =>
  array(2) {
    [0] =>
    string(2) "He"
    [1] =>
    string(2) "He"
  }
  [2] =>
  array(2) {
    [0] =>
    string(5) "world"
    [1] =>
    string(8) "Sunshine"
  }
}

P.S. This answer is posted for the context of the question title after being directed here by a Google search. This was the information I was interested in when searching for this topic.

Solution 4

To group your matches, use parenthesize. EG:

$string = 'bob';
preg_match('/bob/', $string, $matches);

$matches will be ['bob']

preg_match('/(b)(o)(b)/', $string, $matches);

$matches will be ['bob','b','o','b']

Share:
51,887

Related videos on Youtube

carlosdubusm
Author by

carlosdubusm

Updated on November 27, 2020

Comments

  • carlosdubusm
    carlosdubusm over 3 years

    I have the following regex:

    \[([^ -\]]+)( - ([^ -\]]+))+\]
    

    This match the following successfully:

    [abc - def - ghi - jkl]
    

    BUT the match is:

    Array
    (
        [0] => [abc - def - ghi - jkl]
        [1] => abc
        [2] =>  - jkl
        [3] => jkl
    )
    

    What I need is something like this:

    Array
    (
        [0] => [abc - def - ghi - jkl]
        [1] => abc
        [2] =>  - def
        [3] => def
        [4] =>  - ghi
        [5] => ghi
        [6] =>  - jkl
        [7] => jkl
    )
    

    I'm able to do that in C# looking at the groups "captures". How can I do that in PHP?

    • ridgerunner
      ridgerunner about 13 years
      You realize that the - in the character class specifies a range, and your expression ' -\]' means any character from \x20 to \x5D. Thus [^ -\]] is the same thing as [^ !"#$%&'()*+,\-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[‌​\\\]]. You need to escape the dash!
    • Charles
      Charles about 13 years
      Can you show us the regex syntax you would use in C# for this task? From glancing at the docs, the syntax looks pretty much identical to that of the PCRE engine PHP uses. If you had trouble, it'd be interesting dissecting the differences.
  • carlosdubusm
    carlosdubusm about 13 years
    Yeah you are right, not sure why I was complicating the thing so much. Still I would like to know if this can be done in PHP like in C# (where there is like "groups captures")
  • carlosdubusm
    carlosdubusm about 13 years
    Yeah, this works too, thanks. But I'm looking to match and replace on a string like this "[a - b - c] [a] [a - b - f]". So [a] doesn't get replaced but the others do. I solved the issue with preg_replace_callback. Thanks anyway!
  • drudge
    drudge about 13 years
    @carlosdubusm: You should edit your question to include the actual string you're matching against. Otherwise, the answers you get may not work for you. :)
  • SparK
    SparK over 4 years
    your $matches will actually be ['bob', 'b', 'o', 'b']