High schooler
High schooler

Reputation: 1680

Regex getting brackets PHP

I have the following string "<?php jifoafj sfjifasjfoasjfifajs ReadThis(array('type' => 'button', 'value' => 35)) oisfjoijsiofsa sffas ?>"

I am trying to get whatever's inside ReadThis.

This is the Regex so far,

preg_match_all('~<\?(?:php)?\s+ReadThis\(([^)]+)\).*?\?>~s',$thestring,$matches) ;

Ok, but I am getting

array('type' => 'button', 'value' => 35

what I want is

array('type' => 'button', 'value' => 35)

What is the best approach to accomplishing this? Does this have something todo with the Chomsky Hierarchy?

Upvotes: 1

Views: 114

Answers (5)

Ro Yo Mi
Ro Yo Mi

Reputation: 15000

Description

This regex will search your sample string and find the ReadThis and the contents of the outer most set of parans.

<[?](?:php\b)?.*?\s\bReadThis[(]([^)]+[)][^)]*)[)].*?[?]>

enter image description here

Group 0 will receive the entire string, and Group 1 will have the readthis through the last paran.

I modified your search:

  • by placing the special characters inside square brackets
  • added \b after php and before readthis to ensure you don't accidentally find a readthis as part of a larger string
  • after the first close paran, I've added a second match for 0 or more non parans incase you have additional values inside that you wanted to capture.
  • added a second match for the close paran to ensure that it really there

PHP Example

<?php
$sourcestring="<?php jifoafj sfjifasjfoasjfifajs ReadThis(array('type' => 'button', 'value' => 35)) oisfjoijsiofsa sffas ?>";
preg_match_all('/<[?](?:php\b)?.*?\s\bReadThis[(]([^)]+[)][^)]*)[)].*?[?]>/im',$sourcestring,$matches);
echo "<pre>".print_r($matches,true);
?>

$matches Array:
(
    [0] => Array
        (
            [0] => <?php jifoafj sfjifasjfoasjfifajs ReadThis(array('type' => 'button', 'value' => 35)) oisfjoijsiofsa sffas ?>
        )

    [1] => Array
        (
            [0] => array('type' => 'button', 'value' => 35)
        )

)

Upvotes: 0

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89557

You can use this pattern:

ReadThis(\((?:[^()]++|(?1))+\))

Example:

$pattern = '~ReadThis(\((?<result>(?:[^()]++|(?1))+)\))~';
$subject = <<<'LOD'
< ?php jifoafj sfjifasjfoasjfifajs ReadThis(array('type' => 'button', 'value' => 35)) oisfjoijsiofsa sffas  sdfsdf sd
ReadThis(array('type' => 'button', 'value' => 35), 'foo') ? >
LOD;
preg_match_all($pattern, $subject, $matches);
print_r($matches['result']);

you obtain:

array('type' => 'button', 'value' => 35)
array('type' => 'button', 'value' => 35), 'foo'

Upvotes: 1

Nightfirecat
Nightfirecat

Reputation: 11610

It looks to me like your pattern correctly matches the full string, but has the ending paren consumed outside of your capture group... Just move the escape sequence for that paren inside of the capture group instead:

<\?(?:php)?\s+ReadThis\(([^)]+\)).*?\?>

(where your original regex reads this; note the moved backslash)

<\?(?:php)?\s+ReadThis\(([^)]+)\).*?\?>

Upvotes: 1

theo
theo

Reputation: 46

This regex doesn't match anything on this string.

Anyway, to fix your issue juste replace [^)] by a dot like :

~<\?(?:php)?\s+ReadThis\((.+)\).*?\?>~s

Upvotes: 1

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324630

You don't have to match the entire string.

(ReadThis\((array\([^)]+\))\))

The important thing is to capture that closing parens.

Upvotes: 1

Related Questions