1
<?php 

$string = "String is '@Name Surname test @Secondname Surname tomas poas tomas'"

preg_match_all("/@(\w+)(\s)(\w+)/", $string, $matches);

I want extract:

[
0 => '@Name Surname',
1 => '@Secondname Surname',
]

What I get;

array (
  0 => 
  array (
    0 => '@Name Surname',
    1 => '@Secondname Surname',
  ),
  1 => 
  array (
    0 => 'Name',
    1 => 'Secondname',
  ),
  2 => 
  array (
    0 => ' ',
    1 => ' ',
  ),
  3 => 
  array (
    0 => 'Surname',
    1 => 'Surname',
  ),
)
Marcos Pérez Gude
  • 21,869
  • 4
  • 38
  • 69
Wizard
  • 10,985
  • 38
  • 91
  • 165
  • That is how `preg_match_all()` works. 1 subArray = entire Match, 2subArray 1 Capturing group, 3subArray 2 Capturing group, ... – Rizier123 Apr 28 '16 at 08:51

2 Answers2

3

That's the way preg_match_all() and capture groups work.

If you just want the whole names, you need to reduce that to what you need only or use non-capturing parenthesis.

For example:

preg_match_all("/(@\w+\s\w+)/", $string, $matches);

Note that by default:

Orders results so that $matches[0] is an array of full pattern matches, $matches1 is an array of strings matched by the first parenthesized subpattern, and so on.

So you really don't need to capture anything in your case:

preg_match_all("/@\w+\s\w+/", $string, $matches);
jeroen
  • 91,079
  • 21
  • 114
  • 132
2

Use this expression (remove the capture group to spaces)

/@\w+\s\w+/

Test it here:

https://regex101.com/r/cL5xH2/2

Result:

[
0 => '@Name Surname',
1 => '@Secondname Surname',
]
Marcos Pérez Gude
  • 21,869
  • 4
  • 38
  • 69