-2

I would like to split a string efficiently into different sub strings like this :

  <li><a href="">One</a></li><li><a href>Two</a></li><li><a href>Three</a></li>.....<li><a herf>Last</a></li>

I would like to split this string in 3 parts and put each string in a variable.

The first variable $first should contain the first li (<li>One</li>) The second variable $second should contain the rest expect the last (<li>Two</li><li>Three</li>.....) The third variable $third should contain the last li (<li>Last</li>)

Anyone can help ?

Mamadou
  • 2,177
  • 5
  • 31
  • 43
  • $begining_tree = strstr($variable, '', true); $end_tree = strstr($variables, ''); – Mamadou Aug 22 '16 at 10:02
  • And it is exactly like that? With only those tags? – Gynteniuxas Aug 22 '16 at 10:03
  • 1
    Your input string clearly is HTML, so why not treat it as such: Parse the markup (PHP comes with `DOMDocument` as a builtin parser), and iterate over the `li` nodes – Elias Van Ootegem Aug 22 '16 at 10:05
  • exctly like that with those tags – Mamadou Aug 22 '16 at 10:05
  • `DOMDocument` will also give you a handy `DOMNOde` object which has the attributes `->firstChild` and `->lastChild` - so you could then just pull the child nodes and extract the first and last children to give you your 3 vars. – CD001 Aug 22 '16 at 10:07

3 Answers3

1

Should work:

<?php 

$dom = new DOMDocument;
$dom->loadHTML('<li><a href="#">One</a></li><li><a href="#">Two</a></li><li><a href="#">Three</a></li><li><a href="#">Last</a></li>');
$liTags = $dom->getElementsByTagName('li');

$chunks = array();
foreach ($liTags as $li) {
    $chunks[] = '<li>'.strip_tags($li->nodeValue).'</li>';
}

list($first,$second,$third) = array(
   array_slice($chunks,0,1),
   array_slice($chunks,1,count($chunks)-2),
   array_slice($chunks,-1),    
);


?>
Bart
  • 1,268
  • 2
  • 12
  • 14
0

The best thing to do here, because you're dealing with markup, is to treat the data as what it is: HTML. Parse the DOM tree, iterate over the nodes you're interested in and get the data like so:

$dom = new DOMDocument;
$dom->loadHTML($data);//parses the markup string
$li = $dom->getElementsByTagName('li');
$liValues = [];
foreach ($li as $elem) {
    $liValues[] = $elem->textContent; // not nodeValue if the nodes can contain other elements, like in your case an "a" tag
}

To get the first, last and middle elements, just write this:

$length = $li->length; // or count($li); to get the total number of li's
$nodes = [
    $li->item(0), //first
    $li->item(round($length/2)), // middle
    $li->item($length -1), // last
];
//or, given that you don't need the actual nodes
$nodes = [
    $li->item(0)->textContent,
    $li->item(round($length/2))->textContent,
    $li->item($length -1)->textContent,
];

Or just get the parent node (ul or ol), and use $parent->firstChild and $parent->lastChild to get the first and last elements in the list, as CD001 suggested in the comments.

Useful links:

You can use the attributes property of the DOMNode elements in the DOMNodeList returned by getElementsByTagName to further exapand on the data you store

Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
  • @Mamadou: `count($li)` ***should*** work, given that the `DomNodeList` return value implements the `Traversable` interface (so the object supports array access, `foreach` iteration, and `count`) – Elias Van Ootegem Aug 22 '16 at 13:21