Click to See Complete Forum and Search --> : complicated string replacing


PunkSktBrdr01
09-04-2003, 03:45 PM
I know I keep posting regexp problems, but it's confusing for me. Anyway, I'm running a fan fiction site, http://www.radioactiverabbit.com/writing, and I want authors to be able to add chapters to their stories. My idea was that I could add a little code thing, like the ones in one of my other threads, http://forums.webdeveloper.com/showthread.php?s=&threadid=16583. Something like chapter title . Then, when the story is viewed, that is shown as:

Chapter n: chapter title

I tried looking in on php.net, but I can't figure it out. Please help! Thanks!

Oh, also, I want it it to creat links at the top of the page that go down to each chapter. Hope this isn't too much. Thanks!

pyro
09-04-2003, 07:24 PM
Not sure exactly what you are trying to do, but perhaps this is close:

<?PHP
$message = "chapter title";
$message = preg_replace("/\\(.*?)\\[\\/chapter\\]/","<b>Chapter n: <i>$1</i></b>",$message);
echo $message;
?>

Or, this might be even better:

<?PHP
$message = "[chapter=3]chapter title";
$message = preg_replace("/\\[chapter(=?)(\\d*)\\](.*?)\\[\\/chapter\\]/","<b>Chapter $2: <i>$3</i></b>",$message);
echo $message;
?>

PunkSktBrdr01
09-04-2003, 08:58 PM
That's pretty much what I'm looking for. n was supposed to represent the chapter number, though. Is there a way to do this?

pyro
09-04-2003, 09:24 PM
That's why I posted the second example. =3[/b]]chapter title The second bit of PHP will take the 3 and turn it into the chapter number. If that isn't what you want, you'll have to explain what you are trying to achieve a bit better.

PunkSktBrdr01
09-04-2003, 09:41 PM
Well, that's what I want, but I don't want people to have to enter the chapter number. Is there a way to increase the chapter number each time? Perhaps a for loop? Thanks for being so patient.

pyro
09-04-2003, 09:50 PM
How will the script know what chapter is currently the last chapter? Once you get that, the rest is easy...

PunkSktBrdr01
09-04-2003, 10:03 PM
What do you mean? All of the chapters will be displayed on one page, with (hopefully) links at the top to go to each chapter. Each chapter will have an <a name="chn">. Sorry for not being clear before.

pyro
09-04-2003, 10:28 PM
Try something along these lines:

<p><a name="ch1"></a></p>
<p>Chapter 1</p>
<p><a name="ch2"></a></p>
<p>Chapter 2</p>
<p><a name="ch3"></a></p>
<p>Chapter 3</p>
<p><a name="ch27"></a></p>
<p>Chapter 27</p>

<?PHP

#get the current page into the $script_name variable
$self = $_SERVER['PHP_SELF'];
$script = preg_split("/\\//",$self);
$script_name = $script[count($script)-1];

#concatenat all the lines into one variable
$contents = file($script_name);
$lines = "";
foreach ($contents as $line) {
$lines .= $line;
}

#get the last chapter + 1
preg_match_all('/<a name="ch(\\d*)"><\\/a>/',$lines,$matches);
$num = count($matches[1])-1;
$chap_num = $matches[1][$num]+1;

#parse the chapter and display the updated chapter
$message = "chapter title";
$message = preg_replace("/\\[chapter\\](.*?)\\[\\/chapter\\]/","<b>Chapter $chap_num: <i>$1</i></b>",$message);
echo "<p>$message</p>";
?>

Kr|Z
09-05-2003, 08:42 AM
This should replace the chapter-tags with the number increased every time:

$message = "chapter title<br>next chapter title";

preg_match_all("/\[chapter\](.*?)\[\/chapter\]/", $message, $regs);
for($i = 0; $i < count($regs[0]); $i++) {
$message = str_replace($regs[0][$i], "<b>Chapter ".($i + 1).": <i>".$regs[1][$i]."</i></b>", $message);
}

echo $message;

PunkSktBrdr01
09-05-2003, 03:22 PM
Thank you all very much for your help. Now, though, I have another problem. I can't get the replacement of the other formatting to work. Here's the code for the entire formatting-replacement function:

(some of the code doesn't show up 'cause it's the same as vBcode)

function addHtml($story) {
preg_match_all("/<a name=\"ch(\d*)\"><\/a>/", $story, $matches);
$num = count($matches);
for($z = 0, $cnum = 1; $z < $num; $z++, $cnum++) {
$story = preg_replace("/\(.*?)\[\/chapter\]/","<b>Chapter $cnum: $1</b>", $story, 1);
}
$ocode = array('', '', '', '', '[c]', '');
$ohtml = array('<b>', '<i>', '<u>', '<div class="left">', '<div class="center">', '<div class="right">');
$ccode = array('', '', '', '', '', '');
$chtml = array('</b>', '</i>', '</u>', '</div class="left">', '</div class="center>', '</div class="right">');
$bcode = array('[n]', '[tab]', ' ');
$bhtml = array('<br>', '&nbsp;&nbsp;&nbsp;&nbsp;', '&nbsp;');
for($x = 0; $x < count($ocode); $x++) {
$ocode = $ocode[$x];
$ohtml = $ohtml[$h];
$ccode = $ccode[$x];
$chtml = $chtml[$x];
$story = preg_replace("/$ocode(.*?)$ccode/", "$ohtml\$1$chtml", $story);
$story = str_replace($bcode[$x], $bhtml[$x], $story);
}
return $story;
}


The problem is occuring in the preg_replace("/$ocode...). I get a warning message saying "unknown modifier 'b'...". Thanks again for all your help!

pyro
09-05-2003, 05:17 PM
[ / and ] have special meanings in regexp, so you will need to escape them.

[ needs to be \[
/ needs to be \/
and
] needs to be \]

in $ocode, $ccode, and $bcode. So, $bcode would need to look more like this:$bcode = array('\\[n\\]', '\\[tab\\]', ' ');also, line 15 should be (you had the wrong variable defining the index)$ohtml = $ohtml[$x];

PunkSktBrdr01
09-05-2003, 07:16 PM
Well, I did what you suggested, and the error message went away. However, it isn't replacing anything but the chapters. Here's the new code:


function addHtml($story) {
$ocode = array('\[b\]', '\[i\]', '\[u\]', '\[l\]', '\[c\]', '\[r\]');
$ohtml = array('<b>', '<i>', '<u>', '<div class="left">', '<div class="center">', '<div class="right">');
$ccode = array('\[\/b\]', '\[\/i\]', '\[\/u\]', '\[\/l\]', '\[\/c\]', '\[\/r\]');
$chtml = array('</b>', '</i>', '</u>', '</div class="left">', '</div class="center>', '</div class="right">');
$bcode = array('[n]', '[tab]', ' ');
$bhtml = array('<br>', '&nbsp;&nbsp;&nbsp;&nbsp;', '&nbsp;');
for($x = 0; $x < count($ocode); $x++) {
$ocode = $ocode[$x];
$ohtml = $ohtml[$x];
$ccode = $ccode[$x];
$chtml = $chtml[$x];
$story = preg_replace("/$ocode(.*?)$ccode/", "$ohtml\$1$chtml", $story);
$story = str_replace($bcode[$x], $bhtml[$x], $story);
}
preg_match_all("/<a name=\"ch(\d*)\"><\/a>/", $story, $matches);
$num = count($matches);
for($z = 0, $cnum = 1; $z < $num; $z++, $cnum++) {
$story = preg_replace("/\[chapter\](.*?)\[\/chapter\]/","<b>Chapter $cnum: $1</b>", $story, 1);
}
return $story;
}

Any ideas? You've been very helpful!

pyro
09-05-2003, 09:35 PM
I think you'd have better luck without the loop, and seeing how it really isn't saving you much (if any) coding, I'd do it more like this: (note that I used [l], [c], and [r] as those won't be formated by the fourms)

# left
$story = preg_replace("/\\[l\\](.*?)\\[\\/l\\]/","<div class=\"left\">\\\\1</div>",$story);
# center
$story = preg_replace("/\\[c\\](.*?)\\[\\/c\\]/","<div class=\"center\">\\\\1</div>",$story);
# right
$story = preg_replace("/\\[r\\](.*?)\\[\\/r\\]/","<div class=\"right\">\\\\1</div>",$story);
# etc...

PunkSktBrdr01
09-05-2003, 09:40 PM
Okay, thanks! I appreciate your help. You're the greatest!

pyro
09-05-2003, 09:41 PM
I was very happy to help... :)

PunkSktBrdr01
09-06-2003, 12:29 AM
Now that I've got the formatting done, I'm trying to make the links to the chapters using page anchors and a select list which triggers a JavaScript function. I had to change the addHtml() function a bit:


<?
function addHtml($story, $num = "") {
if($num == "") {
preg_match_all("/<a name=\"ch(\d*)\"><\/a>/", $story, $matches);
$num = count($matches);
}
for($z = 0, $cnum = 1; $z < $num; $z++, $cnum++) {
$story = preg_replace("/\[chapter\](.*?)\[\/chapter\]/","<div class=\"center\"><a name=\"ch$cnum\"></a><b>Chapter $cnum: $1</b></div>", $story, 1);
}

$bcode = array('[n]', '[tab]');
$bhtml = array('<br>', '&nbsp;&nbsp;&nbsp;&nbsp;');
for($x = 0; $x < count($bcode); $x++) {
$story = str_replace($bcode[$x], $bhtml[$x], $story);
}

$story = preg_replace("/\[b\](.*?)\[\/b\]/", "<b>$1</b>", $story);
$story = preg_replace("/\[i\](.*?)\[\/i\]/", "<i>$1</i>", $story);
$story = preg_replace("/\[u\](.*?)\[\/u\]/", "<u>$1</u>", $story);
$story = preg_replace("/\[l\](.*?)\[\/l\]/", "<div class=\"left\">$1</div>", $story);
$story = preg_replace("/\[c\](.*?)\[\/c\]/", "<div class=\"center\">$1</div>", $story);
$story = preg_replace("/\[r\](.*?)\[\/r\]/", "<div class=\"right\">$1</div>", $story);

return $story;
}
?>


Anyway, the select list is dynamically generated and has a link to each chapter. All of the chapters are on one page, though, and the link goes to a page anchor. Here's my code for the select list:


<?
if($num_chaps > 0) {
$goto_chap = "<form name=\"chap_form\" onSubmit=\"return false\">\n";
$goto_chap .= "Go to:&nbsp;<select name=\"chap_select\" onChange=\"chapChange(this.options[selectedIndex].value);\">\n";
for($i = 0, $ch = 1; $i < $num_chaps; $i++, $ch++) {
$goto_chap .= "<option value=\"viewstory.php?id=$id#ch$ch\">chapter $ch\n";
}
$goto_chap .= "</select>\n";
$goto_chap .= "</form>\n";
$goto_chap .= "<br><br>\n";
}
else {
$goto_chap = "";
}
?>


The chapChange() JavaScript function:


function chapChange(chapter) {
window.location.href = chapter;
}


If there's a better way to do this, please let me know. Thanks so much!