String in one tag?

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
MarK (CZ)
Forum Contributor
Posts: 239
Joined: Tue Apr 13, 2004 12:51 am
Location: Prague (CZ) / Vienna (A)
Contact:

String in one tag?

Post by MarK (CZ) »

Let's say I have an unknown string. Now, I want to find out, whether it's in one tag or not, like this:
"<b>This is bold text</b>"

but not like this:
"<b>This is bold text</b> and this is not"
or
"<b>This is bold text</b><i>and this is not</i>"

How should I find out? Regex?
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

regex, yes.
User avatar
MarK (CZ)
Forum Contributor
Posts: 239
Joined: Tue Apr 13, 2004 12:51 am
Location: Prague (CZ) / Vienna (A)
Contact:

Post by MarK (CZ) »

I'm still not sure how.

I have this:

Code: Select all

if (mb_ereg("^<([a-zA-Z]+).+</(.+)>$", $item, $parts) &&
    $parts[1] == $parts[2])
but that doesn't fix a string like this:
"<b>This is bold text</b> and <b>this is bold too</b>"
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

The really basic, fairly dumb, PCRE version:

Code: Select all

#^<\s*([a-zA-Z]+)[^>]*>.*?<\s*\\1[^>]*>$#
User avatar
MarK (CZ)
Forum Contributor
Posts: 239
Joined: Tue Apr 13, 2004 12:51 am
Location: Prague (CZ) / Vienna (A)
Contact:

Post by MarK (CZ) »

That one doesn't work.. Why is there the '\\1'?
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

The tags must match.

I forgot a tiny bit:

Code: Select all

<?php

$pattern = '#^<\s*([a-zA-Z]+)[^>]*>.*?<\s*/\s*\\1[^>]*>$#s';
$tests = array(
	'<b>This is bold text</b>' => true,
	'<b>This is bold text</b> and this is not' => false,
	'<b>This is bold text</b><i>and this is not</i>' => false,
);

$results = array();

foreach($tests as $test => $result)
{
	$results[] = (preg_match($pattern, $test) == $result);
}

if (count(array_filter($results)) == count($results))
{
	echo 'it works.';
}
else
{
	echo 'it doesn\'t work.';
	var_dump($results);
}

?>
User avatar
MarK (CZ)
Forum Contributor
Posts: 239
Joined: Tue Apr 13, 2004 12:51 am
Location: Prague (CZ) / Vienna (A)
Contact:

Post by MarK (CZ) »

That is similar to what I've done...

However, your still fails for these:

Code: Select all

'<h1>This is bold text</h2>' => false,
        '<b>This is bold text</b><b>and this is not</b>' => false,
First one is just forgeting about numbers in tags (h1-h6)
but for the second one, mine fails too. I would probably have to parse it as xml and than test it like that, I don't see any way how to fix that via regex.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

You can figure out the first one. The second is a little harder to handle, but not impossible, in a single regex. I won't be writing it however. Keep tinkering around.
User avatar
MarK (CZ)
Forum Contributor
Posts: 239
Joined: Tue Apr 13, 2004 12:51 am
Location: Prague (CZ) / Vienna (A)
Contact:

Post by MarK (CZ) »

Yeah, the first one was no problem of course but I can't see any solution to the second one via regex :?
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

The quick and dirty one I see involves checking to see if the original string matches the matching string. You'd need to remove both anchors for this to work.
Post Reply