Page 1 of 1
How to separate this?
Posted: Thu May 10, 2007 7:17 am
by toasty2
I'm working on a bb code system for my CMS, and one of the tags looks like this:
I need to get home separated from that and into a string (but the word won't always be home), and then I'll replace the whole thing with the home page. I tried learning a little regex and failed, so how would you do it?
Posted: Thu May 10, 2007 11:29 am
by regX
feyd | Please use Code: Select all
and [syntax="..."] tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read: [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]
Code: Select all
<?php
$pattern = '/\\[p\\:([^\\]].*?)\\]/is';
$subject = 'This is a string with [p] in it, and also [p].';
$result = '';
/* to find the first instance use preg_match() */
preg_match($pattern,$subject,$result);
if(is_array($result)){
print_r($result);
}else{
echo 'No matches found in "'.$subject.'".';
}
/* to find all instances use preg_match_all() */
preg_match_all($pattern,$subject,$result);
if(is_array($result)){
print_r($result);
}else{
echo 'No matches found in "'.$subject.'".';
}
?>
If you need an explaination on how to access the matches in $result let me know.
feyd | Please use Code: Select all
and [syntax="..."] tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read: [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]
Posted: Thu May 10, 2007 3:54 pm
by stereofrog
regX wrote:
$pattern = '/\\[p\\:([^\\]].*?)\\]/is';
You actually don't need to double all slashes, because php is smart enough to preserve them.
Posted: Thu May 10, 2007 4:00 pm
by regX
For some reason I distinctly remember my patterns failing when I did not escape the back slashes.
Oh well, good to know now that I don't have to worry about it any longer, lol....Thanks for the tip.
EDIT: I just realised something about the pattern you posted....you aren't using the PCRE 's' modifier, which is why I used the [^] syntax....so if the [P:whatever] is in the middle of the page the expression won't stop matching on a newline char.
Make sense?
Posted: Fri May 11, 2007 5:24 am
by stereofrog
I highly doubt OP wants to allow newlines in a tag body.

Posted: Fri May 11, 2007 8:50 am
by regX
I agree, but that's not what I meant exactly. If the OP wanted to use multiple 'tags' -- tags being the [p:whatever] -- and a single expression, wouldn't the exclusion of the 's' modifier cause the match to stop if a \n or \r is encountered?
I am asking only....I am still a little new to PCRE coming from a VB background, so this is why I am clarifying and asking for clarification.
Posted: Fri May 11, 2007 9:14 am
by stereofrog
/s controls how dot matches, if it's given, dot is equal to everything, if not - to everything except newlines. Here's a small illustration:
Code: Select all
$a = "
[p] [p] [p:spa ces] [p:new
line] [p:yet
ano
ther]
";
$pat = '/\[p:(.*?)\]/i';
preg_match_all($pat, $a, $m);
print_r($m);
$pat .= 's';
preg_match_all($pat, $a, $m);
print_r($m);
Hope this helps.

Posted: Fri May 11, 2007 12:06 pm
by regX
feyd | Please use Code: Select all
and [syntax="..."] tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read: :arrow: [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]
I am doing a poor job of explaining myself I think...
Only one match is returned using preg_match_all() if there are newlines between (for example) tag1 and tag2 and no singleline modifier:
Code: Select all
<?php
ob_start();
$p='/\[p:(.*?)\]/i'; //<-no singleline modifier
//this is what i meant by
//newlines between multiple tags
$a = 'Some text'."\n".' blah [p] and more '."\n".'text and a little [p] more'."\n";
echo $a;
$b=ob_get_contents();
ob_clean();
//will only return the first tag
preg_match_all($p,$b,$m);
print_r($m);
$p.='s'; //<-singleline modifier
//will return both/all tags
preg_match_all($p,$b,$n);
print_r($n);
?>
EDIT: For some reason when I use the PHP bbcode it fubars my :tagX...just removes it from the code block when I submit the post.
feyd | Please use Code: Select all
and [syntax="..."] tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read: :arrow: [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]
Posted: Fri May 11, 2007 1:45 pm
by stereofrog
Did you run your snippet?
Posted: Fri May 11, 2007 2:31 pm
by regX
ROFL, I just did...hahaha, hard to make a case when the script bombs!
Sorry about that -- snippet corrected. And, even after correction both patterns provided the exact same results! :$
Ok, I think I need to start my own thread now, becuase I have some questions about the behavior of PCRE...I have done a ton(ne) of HTML parsing over the past few months using PHP, and the biggest help to me is when I discovered the singleline modifier. Items I knew should be matching weren't, and in another forum 's' was suggested and it ended my nightmares with parsing HTML. Thanks for your patience stereofrog.
@toasty2 -- sorry for jackin your thread, it was unintentional...and use stereofrog's pattern as it appears (most likely is) more efficient.
Posted: Fri May 11, 2007 8:44 pm
by toasty2
It's alright, I waited a day for the controversy to be solved between yall's code. Thanks for the help. I will place you in the credits for my Content Management System, as I will do with all other significant help I receive (this is the first thing so far).
Posted: Mon May 14, 2007 5:39 pm
by toasty2
This is confusing, I'm trying to replace each match with a call to a function with an argument containing the match (without the [p: and the ]). So far I have not been able to figure out a good way to do this. So, first I need to find the matches, replace the whole [p:$name] with showPage($name); I need to do something similar to that, $name being the matched text within the [p: and ].