Jason
Jason

Reputation: 1307

PHP regex, how can I make my regex only return one group?

I have tried the non capturing group option ?:

Here is my data:

hello:"abcdefg"},"other stuff

Here is my regex:

/hello:"(.*?)"}/

Here is what it returns:

Array
(
    [0] => Array
        (
            [0] => hello:"abcdefg"}
        )

    [1] => Array
        (
            [0] => abcdefg
        )

)

I wonder, how can I make it so that [0] => abdefg and that [1] => doesnt exist?

Is there any way to do this? I feel like it would be much cleaner and improve my performance. I understand that regex is simply doing what I told it to do, that is showing me the whole string that it found, and the group inside the string. But how can I make it only return abcdefg, and nothing more? Is this possible to do?

Thanks.

EDIT: I am using the regex on a website that says it uses perl regex. I am not actually using the perl interpreter

EDIT Again: apparently I misread the website. It is indeed using PHP, and it is calling it with this function: preg_match_all('/hello:"(.*?)"}/', 'hello:"abcdefg"},"other stuff', $arr, PREG_PATTERN_ORDER);

I apologize for this error, I fixed the tags.

EDIT Again 2: This is the website http://www.solmetra.com/scripts/regex/index.php

Upvotes: 1

Views: 2208

Answers (2)

AbsoluteƵERØ
AbsoluteƵERØ

Reputation: 7870

preg_match_all

If you want a different captured string, you need to change your regex. Here I'm looking for anything not a double quote " between two quote " characters behind a : colon character.

<?php

$string = 'hello:"abcdefg"},"other stuff';
$pattern = '!(?<=:")[^"]+(?=")!';

preg_match_all($pattern,$string,$matches);

echo $matches[0][0];

?>

Output

abcdefg

If you were to print_r($matches) you would see that you have the default array and the matches in their own additional arrays. So to access the string you would need to use $matches[0][0] which provides the two keys to access the data. But you're always going to have to deal with arrays when you're using preg_match_all.

Array
(
    [0] => Array
        (
            [0] => abcdefg
        )

)

preg_replace

Alternatively, if you were to use preg_replace instead, you could replace all of the contents of the string except for your capture group, and then you wouldn't need to deal with arrays (but you need to know a little more about regex).

<?php
    
    $string = 'hello:"abcdefg"},"other stuff';
    $pattern = '!^[^:]+:"([^"]+)".+$!s';
    
    $new_string = preg_replace($pattern,"$1",$string);
    
    echo $new_string;

?>

Output

abcdefg

Upvotes: 3

gen_Eric
gen_Eric

Reputation: 227200

preg_match_all is returning exactly what is supposed to.

The first element is the entire string that matched the regex. Every other element are the capture groups.

If you just want the the capture group, then just ignore the 1st element.

preg_match_all('/hello:"(.*?)"}/', 'hello:"abcdefg"},"other stuff', $arr, PREG_PATTERN_ORDER);
$firstMatch = $arr[1];

Upvotes: 2

Related Questions