Jump to content
xisto Community
Sign in to follow this  
Houdini

What's Wrong With This Preg_replace Code?

Recommended Posts

I have written a JavaScript that prompts auser for 5 table attributes for entry into the posting area and it produces this:

 

 

[table bd = 15 bgc = green bdc = red cp =10 cs =10]

 

It is then passed through this preg_replace for display in the preview or as a submission in a post:

 

$txt = preg_replace( "#\[table bd=(.+?)bgc=(.+?)bdc=(.+?)cp=(.+?)cs=(.+?)\](.+?)\[/table\]#is", "<table border=\\1bgcolor=\\2bordercolor=\\3cellpadding=\\4cellspacing=\\5>\\6</table>", $txt );

What it produces however is this:

 

<table border = 5 bgc = blue bordercolor = black cp = 9 cs = 2>

When what I want is this:

 

<table border = 5 bgcolor = blue bordercolor = black cellpaddingp = 9 cellspacing = 2>

What is it that is wrong with this code and giving this odd unwanted result? Help would be most certainly appreciated because I am tired of looking at it, my eyes are getting crossed and things are getting blurry.

Share this post


Link to post
Share on other sites

I'm not real good with regular expressions so I can't really answer your problem directly.

 

I usually use two arrays to work my preg_replace magic like I learned in this topic:

http://forums.xisto.com/topic/83250-topic/?findpost=1064298940

 

Here is a more recent and simpler example:

 

I placed certain keywords in strings in my database which are to be replaced by other database entries dependant upon the user.


'@&rank_suffix@si',

'@&rank@si',

'@&size@si',

'@&username@si',

'@&personal@si',

'@&timestamp@si'

);

 

$replace_string = array ($race,

$rank_suffix,

$rank,

$size,

$username,

$personal,

$time

);

 

$output = preg_replace($search_string, $replace_string, $sig_text_item_row[$x]['text_value']);

linenums:0'>// Keyword replacement array here. $search_string = array ('@&race@si', '@&rank_suffix@si', '@&rank@si', '@&size@si', '@&username@si', '@&personal@si', '@&timestamp@si' ); $replace_string = array ($race, $rank_suffix, $rank, $size, $username, $personal, $time ); $output = preg_replace($search_string, $replace_string, $sig_text_item_row[$x]['text_value']);


This is about the easiest example I could even think of which just happens to be the one I did today.

 

Anyway, if the following is true:

$race = "human";$rank = 10;$rank_suffix = "th";$size = 12000;$username = "vujsa";$personal = "My personal message!";$time = mktime();
AND

$sig_text_item_row[$x]['text_value']) = "My name is &usernameand I am currently ranked &rank&rank_suffix with an army of &size &race soldiers.  <br>&personal<br> Page generated at UTC: &timestamp."echo $output;

Would return this:

My name is vujsa and I am currently ranked 10th with an army of 12000 human soldiers.

My personal message!

Page generated at UTC: 1131343747

 


So for your particular example, here is what I would do.


'@bdc@si',

'@bd@si',

'@bgc@si',

'@cp@si',

'@cs@si',

'@\]@si'

);

 

$replace_string = array ("<",

"bordercolor",

"border",

"bgcolor",

"cellpadding",

"cellspacing",

">"

);

 

$output = preg_replace($search_string, $replace_string, $txt);

linenums:0'>// Keyword replacement array here. $search_string = array ('@\[@si', '@bdc@si', '@bd@si', '@bgc@si', '@cp@si', '@cs@si', '@\]@si' ); $replace_string = array ("<", "bordercolor", "border", "bgcolor", "cellpadding", "cellspacing", ">" ); $output = preg_replace($search_string, $replace_string, $txt);


Note: I had to change the order of the array items so that "bdc" would not be returned as "borderc" instead of "bordercolor" because "bd" was found first. Also, I had to escape the brackets.

 

I think that if you used the same method for your replacements, it would be easier to accomplish your goal and easier to spot any bugs that you may have. Also, because this replaces what you know you will have instead of ignoring what you don't know you will have, it requires you to anticipate fewer posibilities in the end. Additionally, the array can be enlarged to allow for other replace requests as well. I like one size fits all functions and routines. Harder to set up I know but easier to request later.

 

I hope this helps some. ;)

 

vujsa

Share this post


Link to post
Share on other sites

I'm positive you could grab these values without using a regular expression, but without seeing the javascript side of things, here's what I would do, in this many steps as well, I hate writing out patterns and replacements all at once.

<?php$txt = '[table bd = 15 bgc = green bdc = red cp =10 cs =10]';$pattern = '#\[table bd = (.+) bgc = (.+) bdc = (.+) cp =(.+) cs =(.+)]#';$replacement = '<table border="\\1" bgcolor="\\2" bordercolor="\\3" cellpadding="\\4" cellspacing="\\5"><tr><td>\\0</td></tr></table>';$txt = preg_replace($pattern, $replacement, $txt);echo $txt;?>

ok, so I'm assuming the output from the javascript is being stored in the variable txt as is. I noticed a problem with your script where you left out white spacing, also '\\6' I replaced with '\\0' as I could not see anywhere with your script that you generated this, so I only used what I had available so I hope you can fix those problems. Considering this is HTML I thought it'd be better to use quotes around values too as well as add in <tr><td></td></tr> for completeness.

Some of these HTML tags I am not fond of due to them being proprietary to the browsers, but most popular browsers have hacked together fixes to work with these tags, yet it's best to keep with standards for consistency.

I hope you'd understand the above, basically I made sure that we take white spacing for granted as well as case sensitivity. I hope in your javascript you make sure that only the correct values can be entered, no special characters unless required and none of the above mentioned keywords. Work on that side of things so as to not allow malicious input.

With the PHP side, I rather see an array of colour name values that could be used and checked against that, there's only 16 allowed web named values of colour, so it's not too much to ask for, then the rest could just be left up to hex values or rgb values in which you can perform checks on those too. Maybe with numeric values, set up a min/max value allow, no input should be converted to 0 (zero) or colour white depending on what it is for.

Cheers,


MC

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...

Important Information

Terms of Use | Privacy Policy | Guidelines | We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.