1

hello i done a code i need some help :) it keep give me nothing , no result

ok here the code

<?php
$f='        <tr class="hover">

            <td class="ra " >3.</td>
            <td class="pla " ><a href="spieler.php?uid=3010">الـعـاصـفـة</a> </td>
            <td class="al " ><a href="allianz.php?aid=127">|BRAVE|</a></td>
            <td class="pop " >2519</td>
            <td class="vil " >6</td>
        </tr>

        <tr class="hover">

            <td class="ra " >3.</td>
            <td class="pla " ><a href="spieler.php?uid=4292">LOOK</a> </td>
            <td class="al " ><a href="allianz.php?aid=127">|BRAVE|</a></td>
            <td class="pop " >2001</td>
            <td class="vil " >5</td>
        </tr>

        <tr class="hover">

            <td class="ra " >4.</td>
            <td class="pla " ><a href="spieler.php?uid=2784">بو سعود</a> </td>
            <td class="al " ><a href="allianz.php?aid=127">|BRAVE|</a></td>
            <td class="pop " >1966</td>
            <td class="vil " >5</td>
        </tr>';
preg_match_all ("/<td class=\"pla \" ><a href=\"spieler.php?uid=(.*)\">(.*)<\/a> <\/td>/", $f, $result , PREG_SET_ORDER);
// putting data to array
foreach($result as $item){
   $player=$item[2];
   $text = "$player
";
print $text;
}



?>

Can some one tell me what is the wrong ? and show mw how to fix it ? thanks alot

2
  • One thing that always gets me is not escaping ? and . in the pattern. Commented Aug 17, 2014 at 21:50
  • Regex should not be used to parse HTML... Commented Aug 18, 2014 at 1:19

2 Answers 2

1

If I'm not wrong @vch and @DirkPitt have already solve a part of your problem.

As an aside, to avoid errors and make your code more readable, you should follow these good practices:

  • when you have a long pattern, use the free-spacing/verbose/comment/extended/... mode. You can switch it on with the x modifier. With this mode, all whitespaces are ignored and inline comments are allowed (after a #). To write a literal space you must put it in a character class or between \Q and \E
  • when you have a pattern that is full of double quotes, use single quotes and vice versa. If your pattern is full of both, use the nowdoc syntax.
  • in the same idea, the slash is not mandatory as delimiter, you can use the tilde or an other character (avoid to use a regex special character even if it is allowed)
  • when you have, in the pattern, a literal substring that may contain regex special characters (like . or ?). Instead of escaping all these characters, you can put the substring between \Q and \E.
  • you can give a name to your capture groups. It's more readable to use something like $m['txt'] instead of $m[1]. you don't need to remember the index.

Example:

$pattern = '~
    \Q<td class="pla " >\E         # these parts are seen as literal strings
    \Q<a href="spieler.php?uid=\E  # whitespaces outside \Q...\E are ignored
    (?<id>  [^"]* ) ">             # named capture id 
    (?<txt> .*? )
    \Q</a> </td>\E ~x';

if (preg_match_all($pattern, $str, $m, PREG_SET_ORDER)) {
    foreach ($m as $v) {
        echo "\nid: " . $v['id'] . "\ttxt: " . $v['txt'];
    }
}

It isn't usually a good idea to parse html with regex because the html language have a very flexible syntax that can hide many traps. For example, if I add a single space here:<td class=" pla " > the pattern will fail. But in your example it is not the case, since all the table seems to have the same structure, whitespaces and indentation.

Here is a more recommended way to do it without regex:

$xpath = new DOMXPath(DOMDocument::loadHTML('<?xml encoding="UTF-8">' . $str));
$linkNodes = $xpath->query('//tr[contains(@class, "hover")]'
                         . '/td[contains(@class, "pla")]/a');

foreach ($linkNodes as $node) {
    echo "\nid: " . explode('=', $node->getAttribute('href'))[1]
       . "\ttxt: " . $node->textContent;
}

Instead of dealing with a string, you are dealing with the DOM tree using paths and attributes to get the target nodes (the 'a' tags). Once you get them, you only need to loop on the nodeList and use the method getAttribute() and the property textContent to obtain what you want.

Sign up to request clarification or add additional context in comments.

Comments

0

Try to use lazy regular expression:

Replace this:

(.*)

With this:

(.*?)

Also escape special signs like . and ?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.