2016-11-03 33 views
17

Próbuję podzielić ciąg w PHP, który wygląda tak:Mecz wszystkie podciągi, które kończą się 4 cyfry za pomocą wyrażeń regularnych

ABCDE1234ABCD1234ABCDEF1234 

do tablicy ciąg, który w tym przypadku będzie wyglądać to:

ABCDE1234 
ABCD1234 
ABCDEF1234 

więc wzór jest „nieokreślonej liczby liter, a następnie 4 cyfry, następnie nieokreślonej liczby liter i 4 cyfr itd.”

Próbuję podzielić ciąg przy użyciu preg_split tak:

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

I zwraca tablicę zawierającą pełny ciąg (nie dzielone) w pierwszym elemencie.

Zgaduję, że problemem jest tutaj mój regex, ponieważ nie do końca rozumiem, jak z nich korzystać, i nie jestem pewien, czy używam go poprawnie.

Więc jaki byłby prawidłowy wyrażeń regularnych do użycia?

+1

Czy jesteś pewien, że nie możesz po prostu podzielić ciągu znaków po cyfrze, po której następuje litera? Z twojego przykładu wydaje się, że możesz to całkowicie zrobić. – user1306322

+0

Dlaczego nie możesz po prostu znaleźć każdego miejsca, w którym masz parę cyfr-liter, która dałaby ci pozycję do zerwania ciągu znaków –

+0

Mogłem to zrobić, nie zdawałem sobie z tego sprawy ... dobrze działa to w ten sposób! – DevBob

Odpowiedz

16

Nie chcesz preg_split, chcesz preg_match_all:

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

wyjściowa:

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

W PHP zastosowano wyrażenia regularne w stylu PCRE, które pozwalają na wykonanie lookbehindów. Możesz go użyć, aby sprawdzić, czy za tobą są 4 cyfry. Łącząc to z uprzedzona, aby zobaczyć, czy jest jakiś list przed wami, a otrzymasz to:

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

Wskazówka przerywane linie na stronie Debuggex Demo. To są punkty, które chcesz podzielić.

W PHP byłoby to:

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

W wyrażeniu "PHP" nie potrzebujesz jawnie sprawdzać 4 cyfr, możesz po prostu sprawdzić cyfrę, a następnie literę? to znaczy. '/ (? <= \ d) (? = [a-z])/i' _ (+ 1) _ – MrWhite

+0

@ w3dk w tym przypadku tak, po prostu lubię moje wyrażenie regularne, gdy jest to możliwe :) – funkwurm

5

stosować zasadę kontrastu:

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

Zobacz a demo on regex101.com.


W PHP byłoby to:

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

Zobacz a demo on ideone.com.

1

Nie jestem dobry w regex więc o to droga mniej podróżował:

<?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);