views:

30

answers:

3

I want to perform a regex using grouping. I am only interested in the grouping, its all I want returned. Is this possible?

$haystack = '<a href="/foo.php">Go To Foo</a>';
$needle = '/href="(.*)">/';
preg_match($needle,$haystack,$matches);
print_r($matches);

//Outputs
//Array ( [0] => href="/foo.php">  [1] => /foo.php ) 

//I want:
//Array ( [0] => /foo.php ) 
+1  A: 

No. The 0 index will always be the text that was matches, not the groups. Of course, you can just remove the first element and renumber the array.

Artefacto
@downvoter Could you explain your objection?
Artefacto
+1  A: 

You could use array_shift() :

array_shift($matches);

but there is no flag to tell preg_match to do what you want.

Anyway, as you know that it will always be there, you should be able to handle this in your code. Why do you want / need this?

Felix Kling
I think you mean "no flag" :p
Artefacto
@Artefacto: Fixed :) thx
Felix Kling
+2  A: 

Actually this is possible with lookarounds. Instead of:

href="(.*)">

You want

(?<=href=").*(?=">)

Now this will match (and therefore capture into group 0) any .* that is preceded by href=" and followed by ">. Note that I highly suspect that you really need .*? instead, i.e. reluctant instead of greedy.

---A--Z---A--Z----
   ^^^^^^^^^^^
      A.*Z

In any case, it looks like PHP's preg is PCRE, so it should support lookarounds.

regular-expressions.info links

  • Lookaround
  • Flavor comparison
    • PHP's preg functions implement the PCRE flavor.
    • PCRE:
      • (?=regex) (positive lookahead): YES
      • (?<=text) (positive lookbehind): fixed + alternation

Demonstration

<?php

$haystack = '<a href="/foo.php">Go To Foo</a><a href="/bar.php">Go To Bar</a>';
$needle = '/(?<=href=").*?(?=">)/';
preg_match_all($needle,$haystack,$matches);
print_r($matches);     

?>

Running this on ideone.com produces:

Array
(
    [0] => Array
        (
            [0] => /foo.php
            [1] => /bar.php
        )

)

Related questions

These are mostly Java, but the regex part covers using lookarounds/assertions:

polygenelubricants
I enjoyed reading this answer, but it does not really answer the original question, since grouping was specifically mentioned.
Artefacto
Sorry if my question was misleading but this is the answer I really needed. After I got over this hurdle I was going to work on generalizing this regex so it could work with multiple links. polygenelubricants' answer already anticipated that. Thank you!