webForumDet fria alternativet

preg_match och längd på sträng

PHP

2 svar · 1 778 visningar · startad av MickeA.com

Medlem sedan feb. 20034 441 inlägg
Frågan#1

Hej!

Har en funktion som använder preg_match som kraschar när strängen man testar är för lång. Det konstiga är att det blir det inte "Memory exhuast" utan browsern säger "The connection timed out".

Inte heller några fel i Apacheloggen. Jag har lyckats leta fram exakt var felet uppstår:

$patt = "/^01(05(2[01](2[235])*(26)?(27)?(28)?(29)?)+15)+70$/";
$str = "0105202627282025262728202526272820252627282026272820252627282025262728202627282026272820252627282026272820262728202627282026272820252525262728202627282025252526272820262728202627282026272820262728150520262728150520262728150520262728150520262728202627282026272820252526272820252627282026272820262728202627282026272820262728202627282026272820262728202627282025262728202627282026272820252627282026272820252627282025262728202526272820252525252627282026272820262728202526272820252627282026272820262728150520202627282026272820262728202627282026272820262728202627281505202627282921262728291505202525262728202526272820252627281505202627282026272820252627282025262728202525262728202627282026272820262728202627282025262728202627282026272815052025262728202525252525262728292025262728291505202526272820262728202627282025262728202525252627282026272820262728202526272820262728202627282026272820262728202627282026272820262728150520262728202627281505202627282026272815052026272815052026272829150520252526272815052026272829202627282915052026272820262728202627282026272820262728202627282026272820262728202525262728150520262728202627282025262728202526272815052025262728150520252627281505202627281505202627282915052026272815052026272820262728150520262728150520252627282920262728292026272829202627282915052026272820262728202627282026272820262728202627282026272820262728202627281570";
preg_match($patt, $str);
string(52) "/^01(05(2[01](2[235])*(26)?(27)?(28)?(29)?)+15)+70$/"
string(1360) "0105202627282025262728202526272820252627282026272820252627282025262728202627282026272820252627282026272820262728202627282026272820252525262728202627282025252526272820262728202627282026272820262728150520262728150520262728150520262728150520262728202627282026272820252526272820252627282026272820262728202627282026272820262728202627282026272820262728202627282025262728202627282026272820252627282026272820252627282025262728202526272820252525252627282026272820262728202526272820252627282026272820262728150520202627282026272820262728202627282026272820262728202627281505202627282921262728291505202525262728202526272820252627281505202627282026272820252627282025262728202525262728202627282026272820262728202627282025262728202627282026272815052025262728202525252525262728292025262728291505202526272820262728202627282025262728202525252627282026272820262728202526272820262728202627282026272820262728202627282026272820262728150520262728202627281505202627282026272815052026272815052026272829150520252526272815052026272829202627282915052026272820262728202627282026272820262728202627282026272820262728202525262728150520262728202627282025262728202526272815052025262728150520252627281505202627281505202627282915052026272815052026272820262728150520262728150520252627282920262728292026272829202627282915052026272820262728202627282026272820262728202627282026272820262728202627281570"

Provar jag med kortare strängar fungerar det utmärkt. Det konstiga är att manualen säger att man kan ställa om pcre.backtrack_limit samt pcre.recursion_limit men det gör ingen skillnad (ja, jag har startat om Apache).

Så, vad är maxlängden för en sträng och preg_match? Har sökt och sökt men hittar inget. Det är inte så att sidan laddar särskilt länge utan "Connection was reset" dyker upp mer eller mindre direkt. Har även provat att ställa om set_time_limit och memory_limit upp till 1GB men blir samma sak.

Några förslag på hur jag löser det här? Vad är egentligen maxlängden?

Tack!

Medlem sedan mars 20034 471 inlägg
#2

Vad händer om du delar upp det i koll av start och slut var för sig?

Alltså:

$pattStart = "/^01(05(2[01](2[235])*";
$pattEnd = "/*(26)?(27)?(28)?(29)?)+15)+70$/";

Med reservation för att det var ett tag sedan jag höll på med regexp, tycker jag det ser ut som om $pattStart kollar de första 10-11 tecknen eller så?
Och $pattEnd kollar 27 tecken eller så?

I så fall borde du kunna kolla:

$str = "0105202627282025262728202526272820252627282026272820252627282025262728202627282026272820252627282026272820262728202627282026272820252525262728202627282025252526272820262728202627282026272820262728150520262728150520262728150520262728150520262728202627282026272820252526272820252627282026272820262728202627282026272820262728202627282026272820262728202627282025262728202627282026272820252627282026272820252627282025262728202526272820252525252627282026272820262728202526272820252627282026272820262728150520202627282026272820262728202627282026272820262728202627281505202627282921262728291505202525262728202526272820252627281505202627282026272820252627282025262728202525262728202627282026272820262728202627282025262728202627282026272815052025262728202525252525262728292025262728291505202526272820262728202627282025262728202525252627282026272820262728202526272820262728202627282026272820262728202627282026272820262728150520262728202627281505202627282026272815052026272815052026272829150520252526272815052026272829202627282915052026272820262728202627282026272820262728202627282026272820262728202525262728150520262728202627282025262728202526272815052025262728150520252627281505202627281505202627282915052026272815052026272820262728150520262728150520252627282920262728292026272829202627282915052026272820262728202627282026272820262728202627282026272820262728202627281570";

$startStr = substring($str, 1, 20); // Längre en $pattStart
-- Pseudokod
$endStr = Substring av sista 40 tecknen eller så //Längre än $pattEnd
preg_match($pattStart, $startStr) && preg_match($pattEnd, $endStr)

Hjälper det?

Om strängen inte alltid är jättelång får du även kolla om den är så lång att den kan delas upp.

Medlem sedan feb. 20034 441 inlägg
#3

Tack för svaret! Men jag tror inte att det går.

Filen jag parsar är en BGMax-fil från Bankgirocentralen, stängen ovan är de två första tecken för varje rad (varje kod motsvarar en post-typ) så om jag klipper den kommer hela parserna sluta att fungera.

Dessutom skiljer sig filerna väldigt mycket, det enda som är gemensamt är att posterna "01" (första raden) samt "70" (sista raden) endast förekommer en gång per fil, övriga poster kan förekomma x antal gånger, alltid i samma ordning, fast olika många.

Sjukt dock att det inte verkar gå att ställa in minnet för preg_match, så att den tillfälligt kan prestera bättre/hantera större strängar.

273 ms totalt · 4 externa anrop · v20260731065814-full.a51de22e
135 ms — deklarationer (db)
0 ms — hämta statistik (cache)
135 ms — hämta tråd, inlägg och bilagor (db)
135 ms — ändringar (db)