2010-12-17 16 views

Antwort

4

, die Berechnung des preg_match_all Ergebnismenge kann nicht eingeschränkt werden. Sie können nur die Ergebnisse begrenzen danach mit array_slice oder array_splice (dies würde PREG_SET_ORDER erforderlich):

preg_match_all($pattern, $subject, $matches, PREG_SET_ORDER); 
$firstMatches = array_slice($matches, 0, 20); 

Aber davon abgesehen, sollten Sie keine regulären Ausdrücke verwenden HTML sowieso zu analysieren. Obwohl moderne reguläre Ausdrücke nicht mehr regulär sind und eine irreguläre Sprache wie HTML verarbeiten können, ist sie zu fehleranfällig. Verwenden Sie stattdessen lieber einen geeigneten HTML-Parser wie den von PHP’s DOM library. Dann nutzen Sie einfach einen Zähler nur bis zu 20 Spiele erhalten:

$doc = new DOMDocument(); 
$doc->loadHTML($code); 
$counter = 20; 
$matches = array(); 
foreach ($doc->getElementsByTagName('p') as $elem) { 
    if ($counter-- <= 0) { 
     break; 
    } 
    $matches[] = $elem; 
} 
+0

Prost Gumbo , dieses DOM-Zeug ist wirklich nützlich. Nie versucht, das anstelle von reg ex auf HTML zu verwenden, also geben Sie es los! – Franco

+0

@SiQ: Beachten Sie, dass * DOMDocument * das von W3C angegebene DOM implementiert und daher ziemlich umfangreich ist; Wenn Sie nur das DOM lesen müssen, können Sie auch [* SimpleXML *] (http://php.net/book.simplexml) ausprobieren. – Gumbo

+0

Ihre DOMDocument-Lösung schränkt den Code auch nachträglich ein, oder? Es legt kein Limit fest, ignoriert jedoch die zusätzlichen Tags, die es gesammelt hat. – bozdoz

3
$matches = array(); 
preg_match_all ($pattern , $subject , $matches); 
$twenty = array_slice($matches , 0, 20); 
3

einfach alle übereinstimmen und in Scheiben schneiden das resultierende Array:

$allMatches = array(); 
$numMatches = preg_match_all($pattern, $subject, $allMatches, PREG_SET_ORDER); 
$limit = 20; 
$limitedResults = $allMatches; 
if($numMatches > $limit) 
{ 
    $limitedResults = array_slice($allMatches, 0, $limit); 
} 

// Use $limitedResults here 
+0

Prost Kumpel, das ist die Art und Weise, die ich in Betracht gezogen hatte. – Franco

0

Ich glaube nicht, aber preg_match hat ein offset Parameter, und auch ein PREG_OFFSET_CAPTURE Flag, das, wenn kombiniert, verwendet werden kann, um die "nächste Übereinstimmung" zu bekommen.

Dies ist vor allem dann nützlich, wenn Sie nicht wollen, alle Ergebnisse zu bekommen und dann array_slice() ein Teil aus: o)

EDIT: Ok, hier ist ein Code (nicht getestet oder in irgendeiner Art und Weise verwendet wird):

$offset = 0; 
$matches = array(); 
for ($i = 0; $i < 20; $i++) { 
    $results = preg_match('/<p(?:.*?)>/', $string, PREG_OFFSET_CAPTURE, $offset); 
    if (empty($results)) { 
     break; 
    } else { 
     $matches[] = $results[0][0]; 
     $offset += $results[0][1]; 
    } 
} 
0

Sie können entweder preg_match_all() verwenden und verwerfen die Spiele Sie nicht interessiert sind, oder Sie können eine Schleife mit preg_match() verwenden. Die zweite Option wäre besser, wenn Sie sich Gedanken über die Kosten machen, die beim Scannen einer großen Zeichenfolge anfallen.

Dieses Beispiel begrenzt auf 2 Ursachen, wenn es tatsächlich 3 in der gesamten Zeichenfolge ist:

<?php 

$str = "ab1ab2ab3ab4c"; 

for ($offset = 0, $n = 0; 
     $n < 2 && preg_match('/b([0-9])/', $str, $matches, PREG_OFFSET_CAPTURE, $offset); 
     ++$n, $offset = $matches[0][1] + 1) { 

     var_dump($matches); 
} 

Wirklich eine while Schleife wahrscheinlich klarer gewesen wäre als eine for Schleife auf Reflexion;)

Verwandte Themen