Page 1 of 1

Replace an instance with an id and recompose the string

Posted: Sun Aug 11, 2013 7:22 pm
by lovelf
Given the following string:

Code: Select all

<b data-uidv="userid1">user full name1</b> likes <b data-uidv="userid2">user full name2</b>
I would have to get both "userid" values out of the string, perform an operation on the database with each one to come with the replacement for

Code: Select all

<b data-uidv="userid1">user full name1</b>
to an x value given from a select in the database by the found id

I would need to recompose the original string with the replacements each made one by one for the matches with a regex.

I am not good at regex, and have tried learning without success.

Thanks

Re: Replace an instance with an id and recompose the string

Posted: Mon Aug 12, 2013 12:32 am
by requinix
Is that the entirety of the string?

Regular expressions are powerful but should only be used when there aren't better tools. In this case you should load the string into something that can parse HTML and grab the data using whatever mechanism it provides.
For example, DOMDocument and DOMXPath can give you those data-uidv values almost directly.

Code: Select all

$html = <<<HTML
<b data-uidv="userid1">user full name1</b> likes <b data-uidv="userid2">user full name2</b>
HTML;

$dom = new DOMDocument();
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
foreach ($xpath->evaluate("//b/@data-uidv") as $node) {
	echo $node->value, "\n";
}

Re: Replace an instance with an id and recompose the string

Posted: Mon Aug 12, 2013 8:15 am
by lovelf
Awesome, thanks.

Re: Replace an instance with an id and recompose the string

Posted: Mon Aug 12, 2013 8:16 am
by lovelf
Now how would I replace right there in the foreach the entire

Code: Select all

<b data-uidv="useridX">user fullnameX</b>
by

Code: Select all

$node->value
for example ?

Re: Replace an instance with an id and recompose the string

Posted: Mon Aug 12, 2013 11:47 am
by lovelf
I think I know how to by using the node value in a str_replace knowing it would start as <b data-uidv="node value"></b>, but how about parsing the b node html as well, maybe in the same foreach so that I get the full string to replace after performing the operation in the database.

Re: Replace an instance with an id and recompose the string

Posted: Mon Aug 12, 2013 12:20 pm
by requinix
Exactly how far will you be taking this "replacing" stuff? XSLT is a really cool way of doing it and gives you a lot of power over altering the HTML, but might be overkill if you merely want to replace in those IDs.

Re: Replace an instance with an id and recompose the string

Posted: Mon Aug 12, 2013 1:39 pm
by lovelf
Yeah, I noticed it takes a bunch of resources, but yes, I would need to replace by knowing the html inside the node which I don't know how to grab inside the foreach that finds the b data-uidv.

Thank you.

Re: Replace an instance with an id and recompose the string

Posted: Mon Aug 12, 2013 2:25 pm
by requinix
Right... I'm asking if there is anything else you'll want to do. Any other potential replacements to make?

For the one you're talking about, replace

Code: Select all

<b data-uidv="useridX">user fullnameX</b>
with

Code: Select all

<b>useridX</b>
?

Re: Replace an instance with an id and recompose the string

Posted: Tue Aug 13, 2013 7:36 am
by lovelf
No more replacements asides those, yes, somewhat like that I'm looking for. I am actually using the id inside this html string to retrieve information about the user and display a link with a tooltip of it grabbed from the database once I know the id, just need to get a replacement for whatever the fullname of the user was at the time the string got inserted to the database, therefore yeah, exactly an example like that I would need.

Thanks so much requinix

Re: Replace an instance with an id and recompose the string

Posted: Tue Aug 13, 2013 12:26 pm
by requinix

Code: Select all

$html = <<<HTML
<b data-uidv="userid1">user full name1</b> likes <b data-uidv="userid2">user full name2</b>
HTML;

$dom = new DOMDocument();
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);

// find everything with a data-uidv
foreach ($xpath->evaluate("//*[@data-uidv]") as $node) {
	$uid = $node->getAttribute("data-uidv");
	$node->removeAttribute("data-uidv");

	// replace with the new content
	$node->nodeValue = "uid {$uid}";
}

// export the html but without the <html> and <body> DOMDocument added
$html = "";
foreach ($xpath->evaluate("/html/body/node()") as $node) {
	$html .= $dom->saveHTML($node);
}

echo $html;