Filter <td> with PHP

Asked

Viewed 798 times

4

I have several <td>

<td>Conteúdo</td>
<td>Conteúdo</td>
<td>Conteúdo</td>
<td>Conteúdo</td>
<td>Conteúdo</td>
<td>Conteúdo</td>

I wanted to share these <td>. For example, I would just like to show the 2, 3, 6. I’m willing to do this because the table I’m pulling is from another site. I wanted to know how to do using PHP.

  • What is this er?

  • Regular Expression, but optional

  • 2

    Tags that only you know what it means should not be used. Tags serve to classify content. I already thought it was Entidade-Relacionamento. It would make more sense to me. And what is optional you can even ask the question but not use a tag.

4 answers

4

You can use Domdocument::loadHTML to parse HTML content, example:

$html = <<<EOF
<table>
<thead>
<tr>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
<th>Col 4</th>
<th>Col 5</th>
<th>Col 6</th>
</tr>
</thead>
<tbody>
<tr>
<td>Conteudo 1</td>
<td>Conteudo 2</td>
<td>Conteudo 3</td>
<td>Conteudo 4</td>
<td>Conteudo 5</td>
<td>Conteudo 6</td>
</tr>
<tr>
<td>Conteudo 1</td>
<td>Conteudo 2</td>
<td>Conteudo 3</td>
<td>Conteudo 4</td>
<td>Conteudo 5</td>
<td>Conteudo 6</td>
</tr>
</tbody>
</table>
EOF;

// criar um novo documento 
$document = new DOMDocument();
// ler o html
$document->loadHTML($html);
// criar seletor xpath
$selector = new DOMXPath($document);
//selecionar conteudo das td's
$results = $selector->query('//td');
// resultado
foreach($results as $node) {
    echo $node->nodeValue . PHP_EOL;
}

Example: Ideone

  • The problem is that it has <thead><tbody> until it reaches the <td>

  • @Alissonacioli, see if my issue solves the problem

4

If I understand what you want to do, you can use a regular expression to capture the tags td that would be so /<td>(.*?)<\/td>/. Note that if there are more tables in this string the expression should be changed.

$str =  "<td>Linha 1</td>" .
        "<td>Linha 2</td>" .
        "<td>Linha 3</td>" .
        "<td>Linha 4</td>" .
        "<td>Linha 5</td>" .
        "<td>Linha 6</td>";

preg_match_all("/<td>(.*?)<\/td>/", $str, $result);

// o array $result[0] possui todas as tags td's encontradas, inclundo a tag
// já o array $result[1] possui apenas o conteúdo das tags td's encontradas
$linhas = $result[1];

echo $linhas[1] . "<br />"; // irá exibir Linha 2
echo $linhas[2] . "<br />"; // irá exibir Linha 3
echo $linhas[5] . "<br />"; // irá exibir Linha 6

2

I think with ER, if possible, it would be more complicated or less readable.

But it’s easy, assuming that this HTML is in a string, and as an alternative to the @abfurlan solution in case the tags should be kept, just break it up, separating by the new lines (and not by the tags), iterate and compare with the index:

$str = '<td>Conteúdo #1</td>
<td>Conteúdo #2</td>
<td>Conteúdo #3</td>
<td>Conteúdo #4</td>
<td>Conteúdo #5</td>
<td>Conteúdo #6</td>';

$tds = explode( "\n", $str );

$slice = array();

array_walk(

    $tds,

    function( $entry, $offset ) use( &$slice ) {
        if( in_array( $offset, array( 1, 2, 5 ) ) ) $slice[] = $entry;
    }
);

I preferred array_walk(), but you can do with a foreach simple, too:

foreach( $tds as $offset => $entry ) {
    if( in_array( $offset, array( 1, 2, 5 ) ) ) $slice[] = $entry;
}

As for having other elements before and after, then the thing changes a little because you have to get to the string you originally posted and didn’t say it was in the middle of more HTML.

For that you have two options:

  • Syntactically parse HTML, with GIFT or Simplexml (which is easier)

    $xml = simplexml_load_string( $str );
    
    $tds = $xml -> xpath( '//td' );
    
    $slice = array();
    
    foreach( $tds as $offset => $entry ) {
        if( in_array( $offset, array( 1, 2, 5 ) ) ) $slice[] = (string) $entry;
    }
    

To the detriment of losing tags.

  • Use Regular Expression to locate <td>:

    $tds = preg_split( '/.*(<td>.*?<\/td>).*/', $str, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
    

The problem with this approach is that you get some garbage that you need to clean up so that the offsets coincide:

    $tds = array_values( array_filter( array_map( 'trim', $tds ) ) );

array_map() how will you apply Trim() in all indexes, array_filter() will remove the empty entries and array_values() will reindexe.

And the iteration remains the same.

  • 1

    Why do you go through the entire array to get the necessary values? Wouldn’t it be simpler and even performatic, for example, to do just like this $slice = array($tds[1], $tds[2], $tds[5]);, or in case there are too many items to be picked up, use this way: foreach (array(1, 2, 5) as $key) $slice[] = $tds[$key];

  • 1

    Yes, yes, it would be better. But the fun of PHP is this, being able to do things in many different ways. But remember to check that $key exists in $tds before using it to not generate Notices. I am happy with the initiative, you apparently understood the answer, unlike many who come, ask, copy the answer and disappear.

0

Since it is from another site try with jquery

$("tr td:nth-child(5)").remove()
$("tr td:nth-child(4)").remove()
$("tr td:first").remove()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table>
  <tr>
    <td>coluna 1</td>
    <td>coluna 2</td>
    <td>coluna 3</td>
    <td>coluna 4</td>
    <td>coluna 5</td>
    <td>coluna 6</td>
  </tr>
</table>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.