Solved

URGENT: Build multidimensional array from mutliple preg_match_all().

Posted on 2004-07-30
9
239 Views
Last Modified: 2013-12-12
This problem is both a little difficult (at least for me) and it is also extremely urgent:

I'm parsing a html-string from a fetched page with "preg_match_all()" several times.

preg_match_all("/[0-9]*\) <font/", $html, $id_matches);   ==>  ARRAY $id_matches containing ids: (1,2,3,4,5,6)

preg_match_all("/[a-z]*\) <font/", $html, $name_matches);   ==>  ARRAY $name_matches containing names: (dick,phil,jack,john,jim,bob)

preg_match_all("/[a-z]*\) <font/", $html, $adress_matches);   ==>  ARRAY $adress_matches containing names: (elm street,paper street,gotham street,lake drive,arlington road,downing street)

how do I build a multidimensional array from that?
Like this

id    |   name   |   adress
1     |   dick     |   elm street
2     |   phil     |   paperstreet

and so on...
0
Comment
Question by:xeta_it
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
9 Comments
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 11675136
Highly NOT recommended.

What happens if the regular expressions don't return the same number of parts for each check?

It is a LOT easier to do the whole regular expression in 1 hit.

From your code though I cannot see how they are working as the second and third regxps are the same so will give the same results.

So, a quick example.
<?php
$sHTMLPage = <<< END_HTML
<html>
<head>
<title>Some data</title>
</head>
<body>
<table border="0">
      <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Address</th>
      </tr>
      <tr>
            <th>1</th>
            <td>John</td>
            <td>123 Acacia Avenue<br>Longbridge<br>London</td>
      </tr>
      <tr>
            <th>2</th>
            <td>Paul</td>
            <td>321 Acacia Avenue<br>Shortbridge<br>London</td>
      </tr>
      <tr>
            <th>3</th>
            <td>Ringo</td>
            <td>999 Acacia Avenue<br>Underbridge<br>London</td>
      </tr>
      <tr>
            <th>4</th>
            <td>George</td>
            <td>666 Acacia Avenue<br>Overbridge<br>London</td>
      </tr>
</table>
</body>
</html>
END_HTML;

// Extract the ID, Name and Address.
preg_match_all('|<tr>.*<th>(\d{1,10})</th>.*<td>(.*)</td>.*<td>(.*)</td>.*</tr>|simU',$sHTMLPage,$aMatches);
echo '<pre>';
print_r($aMatches);
echo '</pre>';
?>

Run this and the output is ...

Array
(
    [0] => Array
        (
            [0] => <tr>
                <th>ID</th>
                <th>Name</th>
                <th>Address</th>
        </tr>
        <tr>
                <th>1</th>
                <td>John</td>
                <td>123 Acacia Avenue<br>Longbridge<br>London</td>
        </tr>
            [1] => <tr>
                <th>2</th>
                <td>Paul</td>
                <td>321 Acacia Avenue<br>Shortbridge<br>London</td>
        </tr>
            [2] => <tr>
                <th>3</th>
                <td>Ringo</td>
                <td>999 Acacia Avenue<br>Underbridge<br>London</td>
        </tr>
            [3] => <tr>
                <th>4</th>
                <td>George</td>
                <td>666 Acacia Avenue<br>Overbridge<br>London</td>
        </tr>
        )

    [1] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
            [3] => 4
        )

    [2] => Array
        (
            [0] => John
            [1] => Paul
            [2] => Ringo
            [3] => George
        )

    [3] => Array
        (
            [0] => 123 Acacia Avenue<br>Longbridge<br>London
            [1] => 321 Acacia Avenue<br>Shortbridge<br>London
            [2] => 999 Acacia Avenue<br>Underbridge<br>London
            [3] => 666 Acacia Avenue<br>Overbridge<br>London
        )

)

$aMatches[1] is the array of IDs.
$aMatches[2] is the array of names.
$aMatches[3] is the array of addresses.

Richard.
0
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 11675153
Now that code is not quite robust enough.

What happens if the source data is missing something.

<?php
$sHTMLPage = <<< END_HTML
<html>
<head>
<title>Some data</title>
</head>
<body>
<table border="0">
      <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Address</th>
      </tr>
      <tr>
            <th>1</th>
            <td>John</td>
            <td>123 Acacia Avenue<br>Longbridge<br>London</td>
      </tr>
      <tr>
            <th>2</th>
            <td>Paul</td>
            <td>321 Acacia Avenue<br>Shortbridge<br>London</td>
      </tr>
      <tr>
            <th>3</th>
            <td>Ringo</td>
            <td>999 Acacia Avenue<br>Underbridge<br>London</td>
      </tr>
      <tr>
            <th>4</th>
            <td>George</td>
            <td>666 Acacia Avenue<br>Overbridge<br>London</td>
      </tr>
      <tr>
            <th></th>
            <td>Richard</td>
            <td>1a Acacia Avenue<br>Nobridge<br>London</td>
      </tr>
      <tr>
            <th>5</th>
            <td></td>
            <td>2b Acacia Avenue<br>Somebridge<br>London</td>
      </tr>
      <tr>
            <th>6</th>
            <td>Sally</td>
            <td></td>
      </tr>
</table>
</body>
</html>
END_HTML;

// Extract the ID, Name and Address.
preg_match_all('|<tr>.*<th>(\d{1,10})?</th>.*<td>(.*)?</td>.*<td>(.*)?</td>.*</tr>|simU',$sHTMLPage,$aMatches);
echo "<pre>\n";
print_r($aMatches);
echo "\n</pre>\n";
?>

Is a better example.

This way you will see that the arrays contain empty elements for the missing data. Using your initial code, the would be no entry at all and you would be only have 6 entries in the list rather than 7.

Richard.
0
 

Author Comment

by:xeta_it
ID: 11675597
Okay, that answer is close to perfect...

The only problem I have is that the kind of array isn't exctacly what i was looking for.
Maybe a missunderstanding.

The array must be able to build like this table:

id    |   name   |   adress
1     |   dick     |   elm street
2     |   phil     |   paperstreet

With the array being built by your example, I'm not getting to the point.

I need to go like this:
<table>
<? foreach ($aMatches as $match){?>
  <tr>
    <td><?  echo match['id'];?></td><td><? echo match['name'];?></td><td><? echo match[''];?></td>
  </tr>
<?} // foreach ?>
</table>


0
Salesforce Has Never Been Easier

Improve and reinforce salesforce training & adoption using WalkMe's digital adoption platform. Start saving on costly employee training by creating fast intuitive Walk-Thrus for Salesforce. Claim your Free Account Now

 

Author Comment

by:xeta_it
ID: 11675634
so basically it would be like flipping the array over 90 Degrees to the side
0
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 11675641
Ok.

Off to lunch. Back in 10.
0
 
LVL 40

Accepted Solution

by:
Richard Quadling earned 500 total points
ID: 11675996
Here is the same example modified to show how to use the arrray.

If you want to produce a new array from the $aMatches one, then that is also present.

<?php
$sHTMLPage = <<< END_HTML
<html>
<head>
<title>Some data</title>
</head>
<body>
<table border="0">
      <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Address</th>
      </tr>
      <tr>
            <th>1</th>
            <td>John</td>
            <td>123 Acacia Avenue<br>Longbridge<br>London</td>
      </tr>
      <tr>
            <th>2</th>
            <td>Paul</td>
            <td>321 Acacia Avenue<br>Shortbridge<br>London</td>
      </tr>
      <tr>
            <th>3</th>
            <td>Ringo</td>
            <td>999 Acacia Avenue<br>Underbridge<br>London</td>
      </tr>
      <tr>
            <th>4</th>
            <td>George</td>
            <td>666 Acacia Avenue<br>Overbridge<br>London</td>
      </tr>
      <tr>
            <th></th>
            <td>Richard</td>
            <td>1a Acacia Avenue<br>Nobridge<br>London</td>
      </tr>
      <tr>
            <th>5</th>
            <td></td>
            <td>2b Acacia Avenue<br>Somebridge<br>London</td>
      </tr>
      <tr>
            <th>6</th>
            <td>Sally</td>
            <td></td>
      </tr>
</table>
</body>
</html>
END_HTML;

// Extract the ID, Name and Address.
preg_match_all('|<tr>.*<th>(\d{1,10})?</th>.*<td>(.*)?</td>.*<td>(.*)?</td>.*</tr>|simU',$sHTMLPage,$aMatches);

$sOutput = '';
$aEntries = array();
foreach($aMatches[1] as $key => $id)
      {
      $sOutput .= <<< END_HTML
      <tr>
            <th>$id</th>
            <td>{$aMatches[2][$key]}</td>
            <td>{$aMatches[3][$key]}</td>
      </tr>

END_HTML;
      $aEntries[$id] = array('name' => $aMatches[2][$key], 'address' => $aMatches[3][$key]);
      }

$sOutput = <<< END_HTML
<html>
<head>
<title>Some data</title>
</head>
<body>
<table border="0">
      <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Address</th>
      </tr>
$sOutput</table>
</body>
</html>
END_HTML;

echo $sOutput;
print_r($aEntries);
?>

Richard.
0
 

Author Comment

by:xeta_it
ID: 11676220
Was still alittle complicated but I got it.

Thanks a lot!!!
0
 

Author Comment

by:xeta_it
ID: 11677274
Okay one last short question...
In your regular Expression you use the modifier U

But this one is responsible for the loss of signs like & @ etc...
How do I get around this... ?

I need the @ sign for emailadresses and the & sign for special characters.
0
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 11677501
U is the ungreedy setting.


<td>(.*)</td>

will capture from the inside of the FIRST <td> to the LAST </td>

Not normally what is required.

Instead ...

<td>(.*?)</td>

is used, but as I would have a LOT of ?, you can use U as a modifier.

You should not be losing any characters.

Can you show your script and what you are looking at?

0

Featured Post

Salesforce Made Easy to Use

On-screen guidance at the moment of need enables you & your employees to focus on the core, you can now boost your adoption rates swiftly and simply with one easy tool.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
if statement malfunction 5 44
Form not executing correctly 1 28
Posting and receiving data with JSON in PHP 12 37
PHP, Curl and XML 13 13
These days socially coordinated efforts have turned into a critical requirement for enterprises.
This article discusses how to create an extensible mechanism for linked drop downs.
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to count occurrences of each item in an array.

739 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question