2011-01-04 6 views
2

Ich habe Schwierigkeiten, meinen regulären Ausdruckscode richtig in PHP zu verwenden. Hier ist mein Code:Regex, um sequenzielle Ganzzahlen zu finden

$array = array(); // Used to satisfy the 3rd argument requirment of preg_match_all. 
$regex = '/(012|345|678|987|654|321|123|456|789|876|543|210|234|567|765|432)/'; 
$subject = '123456'; 
echo preg_match_all($regex, $subject, $array).'<br />'; 
print_r($array); 

Wenn dieser Code lief es folgende Ausgabe:

2 
Array 
(
    [0] => Array 
     (
      [0] => 123 
      [1] => 456 
     ) 
    [1] => Array 
     (
      [0] => 123 
      [1] => 456 
     ) 
) 

Was kann ich tun, damit es 123 übereinstimmen, 234, 345 und 456?

Vielen Dank im Voraus!

+0

| (pipe) Bewirkt, dass die Regex-Engine entweder dem Teil auf der linken Seite oder dem Teil auf der rechten Seite entspricht. Kann zu einer Reihe von Optionen aneinandergereiht werden. –

Antwort

2

Regex ist nicht das richtige Werkzeug für diesen Job (es wird nicht "Sub-Matches" zurückgeben). Verwenden Sie einfach strpos in einer Schleife.

$subject = '123456'; 

$seqs = array('012', '345', '678', '987', '654', '321', '123', '456', '234'); 
foreach ($seqs as $seq) { 
    if (strpos($subject, $seq) !== false) { 
     // found 
    } 
} 
0

Es kann mit regulären Ausdrücken erfolgen. Das Problem mit Ihrem ursprünglichen Code besteht darin, dass sobald eine Übereinstimmung auftritt, das Zeichen verbraucht wird und der reguläre Ausdruck nicht zurückverfolgt wird. Hier ist eine Möglichkeit, es zu tun:

$array = array(); // Used to satisfy the 3rd argument requirment of preg_match_all. 
$regex = '/012|345|678|987|654|321|123|456|789|876|543|210|234|567|765|432/'; 
$subject = '123456'; 

$tempSubject = $subject; 
$finalAnswer = array(); 
do { 
    $matched = preg_match($regex, $tempSubject, $array); 
    $finalAnswer = array_merge($finalAnswer, $array); 
    $tempSubject = substr($tempSubject, 1); 
} while ($matched && (strlen($tempSubject >= 3))); 
print_r($finalAnswer); 

Wie in einer anderen Antwort vorgeschlagen, jedoch möglicherweise nicht von regulären Ausdrücken das richtige Werkzeug seines in dieser Situation zu verwenden, abhängig von Ihrem größeren Ziel. Darüber hinaus ist der obige Code möglicherweise nicht der effizienteste Weg (in Bezug auf Speicher oder Leistung), um dies mit regulären Ausdrücken zu lösen. Es ist nur eine fortschrittliche Lösung für die Erfüllung der Anforderungen.

0

Ja, es ist ein Hack, aber Sie können RegEx verwenden

<?php 
$subject = '123456'; 

$rs = findmatches($subject); 
echo '<pre>'.print_r($rs,true).'</pre><br />'; 


function findmatches($x) { 
    $regex = '/(\d{3})/'; 

    // Loop through the subject string 
    for($counter = 0; $counter <= strlen($x); $counter++) { 
     $y = substr($x, $counter); 
     if(preg_match_all($regex, $y, $array)) { 
      $rs_array[$counter] = array_unique($array); 
     } 
    } 

    // Parse results array 
    foreach($rs_array as $tmp_arr) { 
     $rs[] = $tmp_arr[0][0]; 
    } 
    return $rs; 
} 
?> 

Returns:

Array 
(
    [0] => 123 
    [1] => 234 
    [2] => 345 
    [3] => 456 
) 

Hinweis: Dies wäre nur bei gleichzeitiger Zahlen arbeiten

1
$regex = '/(?=(012|345|678|987|654|321|123|456|789|876|543|210|234|567|765|432))/'; 
$subject = '123456'; 
preg_match_all($regex, $subject, $array); 
print_r($array[1]); 

Ausgabe:

Array 
(
    [0] => 123 
    [1] => 234 
    [2] => 345 
    [3] => 456 
) 

Sie versuchen Übereinstimmungen zu finden, die sich in der Betreffzeile überlappen, was im Allgemeinen nicht möglich ist. In vielen Fällen können Sie es jedoch fälschen, indem Sie den gesamten Regex in eine Erfassungsgruppe einschließen und dann in einem Lookahead einbinden. Da der Lookahead keine Zeichen konsumiert, wenn er übereinstimmt, springt die Regex-Engine nach jeder erfolgreichen Übereinstimmung manuell um eine Position nach vorn, um nicht in einer Endlosschleife stecken zu bleiben. Die Erfassung von Gruppen funktioniert jedoch weiterhin, sodass Sie den erfassten Text wie gewohnt abrufen können.

bemerkt, dass ich nur den Inhalt der ersten Erfassungsgruppe gedruckt ($array[1]). Wenn ich das ganze Array von Arrays gedruckt hatte ($array), hätte es so ausgesehen:

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

    [1] => Array 
    (
     [0] => 123 
     [1] => 234 
     [2] => 345 
     [3] => 456 
    ) 
) 

see it in action on ideone