duanmengsuo9302
2017-01-31 11:46
浏览 95
已采纳

正则表达式一次匹配多次出现

I have this string:

<table width="100%">
    <tr>
      <td width="80" valign="top">
        <b>wo  1 februari</b>
      </td>
      <td>
        <table width="100%">
          <tr class="spits-dagdeel spits-Ochtend">
            <td width="60" valign="top">
              <i>Ochtend</i>
            </td>
            <td>
              <p class="spits-2">lichte spits (2)
               </p>
              <p>De eerste dag van de nieuwe maand, woensdag. Tijdens de ochtend is het vaak rustig op de wegen en dat zal ook nu het geval zijn. We verwachten op het drukste moment niet meer dan 150 kilometer file op de snelwegen.</p>
              <p class="spits-klasse"> Bij een lichte spits wordt tot 150 km verwacht. De normale knelpunten hebben files.
  </p>
            </td>
          </tr>
          <tr class="spits-dagdeel spits-Avond">
            <td width="60" valign="top">
              <i>Avond</i>
            </td>
            <td>
              <p class="spits-3">reguliere spits (3)
               </p>
              <p>Deze spits iets meer drukte dan tijdens de ochtendspits, maar dat is vrij gebruikelijk. We verwachten geen bijzonderheden. Alleen bij ongelukken kunnen files snel in lengte toenemen.</p>
              <p class="spits-klasse"> Bij een reguliere spits wordt tot 225 km verwacht. Alle knelpunten hebben files.
  </p>
            </td>
          </tr>
        </table>
      </td>
    </tr>
  </table>

I want to capture data from string this and save it to my database using a regex.

What I'd like for an output is something like this:

array (
    'date' => 'wo 1 februari',
    'partOfDay' => 'Ochtend',
    'intensity' => 'lichte spits (2)',
    'description' => 'De eerste dag van de nieuwe maand, woensdag. Tijdens de ochtend is het vaak rustig op de wegen en dat zal ook nu het geval zijn. We verwachten op het drukste moment niet meer dan 150 kilometer file op de snelwegen.',
    'default' => 'Bij een lichte spits wordt tot 150 km verwacht. De normale knelpunten hebben files.'
);

array (
    'date' => 'wo 1 februari',
    'partOfDay' => 'Avond',
    'intensity' => 'reguliere spits (3)',
    'description' => 'Deze spits iets meer drukte dan tijdens de ochtendspits, maar dat is vrij gebruikelijk. We verwachten geen bijzonderheden. Alleen bij ongelukken kunnen files snel in lengte toenemen.',
    'default' => 'Bij een reguliere spits wordt tot 225 km verwacht. Alle knelpunten hebben files.'
);

Only I have no idea of how to do this in the most efficient way.

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • donglinxi1467 2017-01-31 13:04
    已采纳

    If you table structure is fixed you can try this:

    $dom = new domDocument();
    $dom->loadHTML($text);//$text is your table
    $dom->preserveWhiteSpace = false;
    $tables = $dom->getElementsByTagName('table');
    $table = $tables->item(1);
    $keys=array('partOfDay','intensity','description','default');
    $arr=array();
    $dt=$tables->item(0);
    $x=0;
    foreach($dt->childNodes as $dates){
        foreach ($dates->childNodes as $k=>$data){
        $date=$data->nodeValue;break;
        }
    
    }
    foreach ($table->childNodes as $key=>$td) {
        $arr[$key]['date']=$date;
        $i=0;
        foreach ($td->childNodes as $k=>$data){
            if($data->hasChildNodes()){
                foreach($data->childNodes as $datum){
                   if(!empty($datum->tagName)){
                 if(strcmp($datum->tagName ,"p")==0 || strcmp($datum->tagName ,"i") == 0 ){
                  $arr[$key][$keys[$i]]=$datum->nodeValue;
                  $i++;
                }
                   }
                }
    
            }
    
    } 
    }
    

    DEMO HERE

    点赞 打赏 评论
  • dongwu9063 2017-01-31 11:57

    I think that the regex is not the best option: the whitespace characters can change, the webmaster could decide to compress the html and in these cases you need to rewrite your whole regex (which will be a huge and long mess).

    The best move is to use a DOM Crawler like the Symfony DOM Crawler.

    Using with composer

    create a blank composer project and require the dom crawler package:

    composer init
    composer require symfony/dom-crawler
    

    PHP file

    require_once "vendor/autoload.php"
    
    use Symfony\Component\DomCrawler\Crawler;
    
    $html = <<<'HTML'
    <!DOCTYPE html>
    <html>
        <body>
            <p class="message">Hello World!</p>
            <p>Hello Crawler!</p>
        </body>
    </html>
    HTML;
    
    $crawler = new Crawler($html);
    
    foreach ($crawler as $domElement) {
        var_dump($domElement->nodeName);
    }
    

    P.s.: I had a similar task a few month ago, and I tried with regex, but after a while I realized that the best tool for this kind of job is a DOM Crawler

    点赞 打赏 评论

相关推荐 更多相似问题