How to separate this?

Any questions involving matching text strings to patterns - the pattern is called a "regular expression."

Moderator: General Moderators

Post Reply
toasty2
Forum Contributor
Posts: 361
Joined: Wed Aug 03, 2005 10:28 am
Location: Arkansas, USA

How to separate this?

Post by toasty2 »

I'm working on a bb code system for my CMS, and one of the tags looks like this:

Code: Select all

[p:home]
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?
User avatar
regX
Forum Newbie
Posts: 23
Joined: Thu May 10, 2007 9:33 am
Location: USA

Post by regX »

feyd | Please use

Code: Select all

,

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

,

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]
User avatar
stereofrog
Forum Contributor
Posts: 386
Joined: Mon Dec 04, 2006 6:10 am

Post by stereofrog »

regX wrote:
$pattern = '/\\[p\\:([^\\]].*?)\\]/is';
You actually don't need to double all slashes, because php is smart enough to preserve them.

Code: Select all

$pattern = '/\[p:(.*?)\]/i';
User avatar
regX
Forum Newbie
Posts: 23
Joined: Thu May 10, 2007 9:33 am
Location: USA

Post 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?
User avatar
stereofrog
Forum Contributor
Posts: 386
Joined: Mon Dec 04, 2006 6:10 am

Post by stereofrog »

I highly doubt OP wants to allow newlines in a tag body. ;)
User avatar
regX
Forum Newbie
Posts: 23
Joined: Thu May 10, 2007 9:33 am
Location: USA

Post 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.
User avatar
stereofrog
Forum Contributor
Posts: 386
Joined: Mon Dec 04, 2006 6:10 am

Post 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. ;)
User avatar
regX
Forum Newbie
Posts: 23
Joined: Thu May 10, 2007 9:33 am
Location: USA

Post by regX »

feyd | Please use

Code: Select all

,

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

,

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]
Last edited by regX on Fri May 11, 2007 2:33 pm, edited 1 time in total.
User avatar
stereofrog
Forum Contributor
Posts: 386
Joined: Mon Dec 04, 2006 6:10 am

Post by stereofrog »

Did you run your snippet?
User avatar
regX
Forum Newbie
Posts: 23
Joined: Thu May 10, 2007 9:33 am
Location: USA

Post 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.
toasty2
Forum Contributor
Posts: 361
Joined: Wed Aug 03, 2005 10:28 am
Location: Arkansas, USA

Post 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).
toasty2
Forum Contributor
Posts: 361
Joined: Wed Aug 03, 2005 10:28 am
Location: Arkansas, USA

Post 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 ].
Post Reply