php Regex never my strong side :P

Hi All,

I want to create a custom tag for a site and i need some regex to work through the parameters.

let's say that i've got a string that holds a bunch of text / html and also contains this tag
[customtag type="test" width="120" height="233"]

I would like to end up with
$customtag as an array
$customtag['type'] = 'test'
$customtag['width'] = 120
etc.

here's what i got so far:

$pattern = '#\\[customtag([^\]]+)\]#smi';
preg_match_all($pattern, $content, $matches);

echo $matches; 

but how do I pregmatch the matches to get the different attributes out in an array? 


 

Open in new window


LVL 13
p_nutsAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Scott MadeiraCommented:
I wouldn't use regular expressions once I go to this point.  I'd use standard PHP functions to get what you need.


 
<?php

// Break string into pieces where there is a space
$matchlist = explode(' ',$matches);

// Loop through each segment of the matchlist
foreach ($matchlist as $value){
     
    // if the value is not customtag then split it at the = sign
    // You may have to strip off the quotes if you don't want them as part of the string 
    if ($value != 'customtag'){
    	$attr = explode('=', $value);
    	$customtag[$attr[0] = $attr[1];    	
    }

}


?>

Open in new window

0
Scott MadeiraCommented:
Note: line 13 is missing a closing bracket ']'  Should be:  

$customtag[$attr[0]] = $attr[1];
0
ChrissalterCommented:
Havent done php for a while but a really good resource for regex is

http://www.txt2re.com

Creates the code for you :0)
0
Why Diversity in Tech Matters

Kesha Williams, certified professional and software developer, explores the imbalance of diversity in the world of technology -- especially when it comes to hiring women. She showcases ways she's making a difference through the Colors of STEM program.

Lukasz ChmielewskiCommented:
Take a look at this example:

<?php
	$file = '[customtag type="test" width="120" height="233"]';
	preg_match("/\[customtag type=\"([^\"]+)\" width=\"([^\"]+)\" height=\"([^\"]+)\"\]/", $file, $matches);
	print_r($matches);
?>

Open in new window


The array holds the parameters you want.
0
Lukasz ChmielewskiCommented:
You may find this link accurate for your needs in the future:
http://gskinner.com/RegExr/
0
p_nutsAuthor Commented:
hi Roads_Road

i like your example but I want to make it so that the attributes are optional.

how would you do that?
0
p_nutsAuthor Commented:
also what if a user changes the order of the attributes
0
Lukasz ChmielewskiCommented:
That requires a more complex regex - can you post an example of few ones you want to include ?
0
p_nutsAuthor Commented:
$file = 'html stuff [customtag type="test" width="120"  height="233"] more html stuff.';

that's it.

0
p_nutsAuthor Commented:
where type is always needed.. width and height are optional .. and i would like this to be as flexible as possible so the order shouldn't matter.
0
Ray PaseurCommented:
Given the test data, this works.  But note that your output from this is highly dependent on the test data.  Try deleting the second $str and running it with a more comprehensive set of test data and you will see what I mean.
http://www.laprbass.com/RAY_temp_pnuts.php

You might want to consider what will happen if you have more than one of these tags.  Just a thought, ~Ray
<?php // RAY_temp_pnuts.php
error_reporting(E_ALL);
echo "<pre>";

// TEST DATA
$str = 'html stuff [customtag type="test" width="120"  height="233"] more html stuff [customtag type="test" width="240"  height="1"] html stuff [othertag type="work" width="120"  ] more html stuff.';
$str = 'html stuff [customtag type="test" width="120"  height="233"] more html stuff.';
var_dump($str);

// A REGEX TO FIND ALL THE BRACKETED STRINGS
$rgx
= '#'        // REGEX DELIMITER
. '\['       // ESCAPED BRACKET
. '(.*?)'    // GROUP OF ANYTHING UNGREEDY
. '\]'       // ESCAPED BRACKET
. '#'        // REGEX DELIMITER
;

preg_match_all($rgx, $str, $mat);

$out = array();
foreach ($mat[1] as $str)
{
    // REMOVE THE NOISE
    $str = str_replace('"', NULL, $str);
    $str = str_replace("'", NULL, $str);
    $str = preg_replace('#\s\s+#', ' ', $str);
    $str = trim($str);

    // BREAK THE TAG APART
    $arr = explode(' ', $str);
    $ndx = $arr[0];
    unset($arr[0]);
    $out[$ndx] = array();

    // EXTRACT EACH KEY-VALUE PAIR
    foreach ($arr as $kvp)
    {
        $knp = explode('=', $kvp);
        $out[$ndx][$knp[0]] = $knp[1];
    }

}
var_dump($out);

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
p_nutsAuthor Commented:
wouldn't that just be a case of adjusting the regex pattern to match the type?

0
Terry WoodsIT GuruCommented:
Ray's code looks pretty good to me, so I won't even try creating my own solution. Post another comment if you get stuck though.
0
Ray PaseurCommented:
just be a case of adjusting the regex pattern -- No, I think it would be more a case of adjusting the entire design pattern.  There are three numbers that matter in computer programming: zero, one and infinity.  Your question and test case works well for one.  It fails for more than one if there is any duplication of a tag in the input string.  This is not a regex question, it is a data and design question.

If you want to post a new question and include a larger test data set, you might find more interesting solutions to this issue.  But if the test data posted at ID:37309318 is all we have, then the question is completely answered.

Best regards, ~Ray
0
Scott MadeiraCommented:
I'll go back to my original question / idea in post ID 37308486.  Why do you want to solve this problem with a RegEx?  

As you have seen from the other posts, the regex method is not trivial and may not be possible if the parameters in your data change.

0
p_nutsAuthor Commented:
hi ray. et all..

the multiple issue was actually a quick fix. as i replace the content i just did a preg_replace and limit it to 1 so it would only do the actual customtag that it was working on.

so it's time for points..

thanks all!

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.