Avatar billede firestone Nybegynder
29. februar 2008 - 12:09 Der er 9 kommentarer og
2 løsninger

Match 1 eller flere parametre i regex, med php

Jeg har med hjælp fået lavet følgende fungerende kode, som parser linier efter et mønster, jeg har så efterfølgende erfaret at nogen gange logger mit andet program ikke alle parametere og så matcher den ikke mere.. så jeg skal have lavet [ AON: 1 BON: 1 CONS: 11 DON: 12MB ] [INFO: email.send.to.admin ] felterne optional, så de ikke skal være til stede for at den matcher.
eks: 2007.02.28-MATCHING_STRING-OK [ AON: 1 CONS: 11 ]

jeg har rodet en del med ()? men det syntes ikke lige at fungere, en der har noget feedback som jeg kan bruge?

<?PHP
$indData = "2007.02.28-INCIDENT_MATCHING_STRING-ERR [ AON: 1 BON: 1 CONS: 11 DON: 12MB ] [INFO: email.se
nd.to.admin ]";
$pattern = "(.*?)-(.*?)\[ AON: (.*?) BON: (.*?) CONS: (.*?) DON: (.*?) \] \[INFO: (.*?) \]";
$phpPattern = "/$pattern/";
preg_match_all($phpPattern, $indData, $matches);
$noOfCaptures = count($matches[0]);
for ($capture = 0; $capture < $noOfCaptures; $capture++) {
    $date    = $matches[1][$capture];
    $incident = $matches[2][$capture];
    $AON      = $matches[3][$capture];
    $BON      = $matches[4][$capture];
    $CONS    = $matches[5][$capture];
    $DON      = $matches[6][$capture];
    $INFO    = $matches[7][$capture];
var_dump($AON);
var_dump($phpPattern, $indData, $matches);
}
echo $date . '<br>';
echo $incident . '<br>';
echo $AON . '<br>';
echo $BON . '<br>';
echo $CONS . ' <br>';
echo $DON . '<br>';
echo $INFO . '<br>;
?>
Avatar billede firestone Nybegynder
29. februar 2008 - 12:56 #1
sidste linie skal selvfølgelig være sådan her echo $INFO . '<br>';
Avatar billede firestone Nybegynder
05. marts 2008 - 15:42 #2
$pattern = "(.*?)-(.*?)\[ AON: (.*?) BON: (.*?) CONS: (.*?) DON: (.*?) \] \[INFO: (.*?) \]";

Hvis AON BON eller lign ikke findes så matcher den ikke, hvad kan jeg gøre for at fange dem også?
Avatar billede nielle Nybegynder
05. marts 2008 - 19:58 #3
Det afhænger af hvordan den så ser ud når der mangler en af parametrene. Det har du ikke vist os.

Men prøv med denne her:

$pattern = "(.*?)-(.*?) \[(?: AON: (.*?))?(?: BON: (.*?))?(?: CONS: (.*?)?)(?: DON: (.*?))? \] \[INFO: (.*?) \]";
Avatar billede firestone Nybegynder
06. marts 2008 - 08:59 #4
Jeg tænkte på om ikke det var muligt at kombinere (AON: (.*?)|BON: (.*?))? ? tegnet | betyder jo "eller"
Avatar billede nielle Nybegynder
06. marts 2008 - 18:03 #5
Næppe... Så matcher den godt nok når den ene af dem mangler, men den fejler så til gengæld når begge er tilstede.

Har du prøvet mit forslag?
Avatar billede firestone Nybegynder
07. marts 2008 - 09:09 #6
Den matcher ikke nogen af dem, hvis du deler den lidt op, hvad er det så egentligt ?: gør?
Avatar billede nielle Nybegynder
07. marts 2008 - 15:51 #7
I mine tests matcher den ellers fint. Men det er måske fordi at jeg har gjort nogle antagelser om hvordan at tekststrengen ser ud hvis der mangler et led. Muligvis er min antagelse forkert - men det ved jeg først hvis du viser et eksempel på hvor dan det ser ud når at der mangler noget (komplet med hvor mange blanktegn der så er tilbage og den slags ting - altså et eksempel fra den "virkelige verden").

Når der står (?: ... ) er det egentlig blot det samme som ( ... ) - pointen er at den 1. version ikke forsøger at gemme det der bliver matchet i parentesen i $matches array'et, mens at den 2. version gør.

Jeg skriver i virkeligheden:

(?: ... )?

for at matche et led som nogen gange er der og andre gange ikke er der - det er det ?-tegnet i enden gør. Dette kunne lige så godt være gjort med:

( ... )?

men siden at jeg ikke var interesseret i *hvad* der står på pladsen, men kun *om* den var der eller ej så det blev derfor med "?:".
Avatar billede firestone Nybegynder
10. marts 2008 - 09:29 #8
(.*?)-(.*?)\[\s*(AON:\s*(\d+)\s*)?(BON:\s*(\d+)\s*)?(CONS:\s*(\d+)\s*)?(DON:\s*([^\]]+)\s*)?\](\s*\[\s*INFO:\s+([^\}]+)\])?
Den her linie matcher det jeg var ude efter, efter mange timers trial and error.
Men nielle send lige et svar du har ihvertfald fortjent halvdelen af de points her, som tak for den indsats du har udført.
Avatar billede nielle Nybegynder
10. marts 2008 - 09:47 #9
Du kan som sagt ændre sådan noget som:

(AON:\s*(\d+)\s*)?

til:

(?:AON:\s*(\d+)\s*)?

og dermed få en lidt mere effektiv regexp ud af det.

Desuden synes jeg at det ser ud til at være en smule overkill med alle de \s*. Det må altså kunne gøres mere simpelt end det
Avatar billede firestone Nybegynder
10. marts 2008 - 09:48 #10
Takker for dialogen, det har hjulpet meget.
Avatar billede nielle Nybegynder
10. marts 2008 - 18:11 #11
Takker for point :^)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester