2016-11-03 1 views
17

Ich versuche, eine Zeichenfolge in PHP zu spalten, die wie folgt aussieht:Spiel aller Substrings, die mit 4 Ziffern mit regulären Ausdrücken Ende

ABCDE1234ABCD1234ABCDEF1234 

in einem Array von String, der in diesem Fall aussehen würde, dies:

ABCDE1234 
ABCD1234 
ABCDEF1234 

So ist das Muster „eine unbestimmte Anzahl von Buchstaben, und dann 4 Ziffern, dann eine unbestimmte Anzahl von Buchstaben und 4 Ziffern usw.“

Ich versuche, die Zeichenfolge mit preg_split wie folgt aufgeteilt:

$pattern = "#[0-9]{4}$#"; 
preg_split($pattern, $stringToSplit); 

Und es gibt einen Array die vollständige Zeichenfolge (nicht geteilt) im ersten Elemente enthält.

Ich vermute das Problem hier ist meine Regex, da ich nicht vollständig verstehe, wie man sie verwendet, und ich bin mir nicht sicher, ob ich es richtig verwende.

Also, was wäre die richtige Regex zu verwenden?

+1

Sind Sie sicher, obwohl Sie die Zeichenfolge nicht teilen können, nachdem auf eine Zahl ein Buchstabe folgt? Aus Ihrem Beispiel scheint es, als könnten Sie das tun. – user1306322

+0

Warum können Sie nicht einfach jeden Platz finden, wo Sie ein Ziffern-Buchstaben-Paar haben, das Ihnen die Positionen zum Brechen der Saite geben würde? –

+0

Könnte das getan haben, ich habe es nicht bemerkt ... nun, es funktioniert so! – DevBob

Antwort

16

Sie wollen nicht preg_split, möchten Sie preg_match_all:

$str = 'ABCDE1234ABCD1234ABCDEF1234'; 
preg_match_all('/[a-z]+[0-9]{4}/i', $str, $matches); 
var_dump($matches); 

Ausgang:

array(1) { 
    [0]=> 
    array(3) { 
    [0]=> 
    string(9) "ABCDE1234" 
    [1]=> 
    string(8) "ABCD1234" 
    [2]=> 
    string(10) "ABCDEF1234" 
    } 
} 
7

PHP verwendet PCRE-Stil Regexes, die Sie Lookbehinds tun können. Sie können dies verwenden, um zu sehen, ob sich 4 Ziffern hinter Ihnen befinden. Kombiniert man dies mit einem Look-Ahead, um zu sehen, ob es ein Brief vor dir ist, und Sie diese:

(?<=\d{4})(?=[a-z]) 

Hinweis die gepunkteten Linien auf der Debuggex Demo Seite. Das sind die Punkte, auf die Sie aufteilen möchten.

In PHP wäre dies:

var_dump(preg_split('/(?<=\d{4})(?=[a-z])/i', 'ABCDE1234ABCD1234ABCDEF1234')); 
+0

In der "PHP" Regex scheinen Sie nicht explizit nach 4 Ziffern zu suchen, Sie könnten einfach nach einer Ziffer suchen, gefolgt von einem Buchstaben? dh. '/ (? <= \ d) (? = [a-z])/i' _ (+ 1) _ – MrWhite

+0

@ w3dk in diesem Fall ja, ich mag meine Regex explizit wenn möglich :) – funkwurm

5

Verwenden Sie das Prinzip des Kontrastes:

\D+\d{4} 
# requires at least one non digit 
# followed by exactly four digits 

Siehe a demo on regex101.com.


In PHP dies wäre:

<?php 
$string = 'ABCDE1234ABCD1234ABCDEF1234'; 
$regex = '~\D+\d{4}~'; 
preg_match_all($regex, $string, $matches); 
?> 

Siehe a demo on ideone.com.

1

Ich bin nicht gut in regex so ist hier die weniger befahrene Straße:

<?php 
$s = 'ABCDE1234ABCD1234ABCDEF1234'; 
$nums = range(0,9); 

$num_hit = 0; 
$i = 0; 
$arr = array(); 

foreach(str_split($s) as $v) 
{ 
    if(isset($nums[$v])) 
    { 
     ++$num_hit; 
    } 

    if(!isset($arr[$i])) 
    { 
     $arr[$i] = ''; 
    } 

    $arr[$i].= $v; 

    if($num_hit === 4) 
    { 
     ++$i; 
     $num_hit = 0; 
    } 
} 

print_r($arr); 
Verwandte Themen