webForumDet fria alternativet

reguljära uttryck (igen)

PHP

16 svar · 650 visningar · startad av Patrik81

Medlem sedan okt. 2001538 inlägg
Frågan#1

Hejsan, nu sitter jag här med ett nytt problem igen.

Jag försökte skriva ett uttyck för att kontrollera en datumsträng. Det funkade nästan, men med några större fel.

Antagligen har jag skrivit den helt åt helsike fel, så jag bifogar både den, och skriver vad målet är, i hopp om att någon antingen kan skriva om den, eller kan hitta ett smartare sätt att göra det på.

19|2[01]{1}[0-9]{2}-{1}
0[1-9]|1[0-2]{1}-{1}
(0[1-9]|[12][0-9]|3[0-2]){1}-{1}
([01][0-9]|2[0-3]){1}:{1}
((0[1-9]|[1-5][0-9]){1}:?){2}

(Har allt på en rad i scriptet, men kortade av den här så att den inte blir så hiskeligt lång.

Målet är alltså att kolla att ett datum ligger inom
1900-01-01 00:00:00
och
2199-12-31 23:59:59

Datumsträngen kommer alltså alltid att vara 19 tecken lång.

Just nu så validerar mitt uttryck även datum såsom 1900-00-00 24:60:60 och det är lite kass, för varken månad eller dag noll finns ju, och 24:60:60 skall ju vara 00:00:00 så det borde inte heller gå igenom.

Någon som orkar hjälpa mig?

MVH Patrik

Medlem sedan aug. 2000374 inlägg
#2

Verkar som du försöker göra det mer komplicerat än var det är.

Använd ett enklare regexp och validera efter du matchat.

/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})/
Medlem sedan maj 2004693 inlägg
#3

Hansen skrev:

Verkar som du försöker göra det mer komplicerat än var det är.

Använd ett enklare regexp och validera efter du matchat.

/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})/

koden kommer inte funka...du kommer kunna skriva tex

2199-12-31 23:59:59 vilket är OK men även

9199-12-31 23:59:59 vilket den inte ska acceptera

Medlem sedan maj 2004693 inlägg
#4

prova denna...jag är dock inte 100% säker

/^(19|2[01]){1}([0-9]){2}(-){1}(0[0123456789]|1[012]){1}(-){1}(0[123456789]|1[0123456789]|2[0123456789]|3[01]){1}([ ]){1}(0|1|2){1}([0-9]){1}([:]){1}([0-5]){1}([0-9]){1}([:]){1}([0-5]){1}([0-9]){1}$/

observera att man kan skriva in 02.31 (31a februari). Men som vi vet så har inte februari så många dagar :) . Jag är inte en tillräckligt advancerad programmerare för att fixa det ;)

Kanske skulle du kunna ha 4 olika if satser som kollar vad det är för månad och kör olika regexp. 1 för 31 dgar. 1 för 30, 1 för 28 och en som kör för 29dagar (skottår)

Medlem sedan aug. 2000374 inlägg
#5

kobranturre skrev:

Hansen skrev:

Verkar som du försöker göra det mer komplicerat än var det är.

Använd ett enklare regexp och validera efter du matchat.

/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})/

koden kommer inte funka...du kommer kunna skriva tex

2199-12-31 23:59:59 vilket är OK men även

9199-12-31 23:59:59 vilket den inte ska acceptera

<?php

if ( validate_datetime("2004-08-18 12:35") ) {
    echo "Goodie!\n";
}

function validate_datetime($date) {
    
    if ( preg_match("/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})/", $date, $matches ) ) {
            
        #year
        if ( !( $matches[1] > 1900 and $matches[1] < 2199 ) ) {
            return false;
        }
        
        # osv...
        
        return true;
    }

    return false;
}
?>

redigering: tog bort den sista onödiga else satsen

Medlem sedan maj 2004693 inlägg
#6

Koden fungerar iaf inte

/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})/

säger:

4siffror-2siffror-2siffror 2siffror:2siffror:2siffror

dvs den skulle godkänna

9999-99-99 99:99:99

då måste du använda if-satser till

årtalet
månaden
dagen
timmen
minuten
sekunden

med andra ord: Allt

Medlem sedan maj 200010 687 inlägg
#7

kobranturre skrev:

koden kommer inte funka...du kommer kunna skriva tex

2199-12-31 23:59:59 vilket är OK men även

9199-12-31 23:59:59 vilket den inte ska acceptera

Hansen skrev ju "validera efter du matchat.". Och jag håller med Hansen.

Medlem sedan maj 200010 687 inlägg
#8

Förresten har inte PHP något inbyggt för att kolla sånt här?
Blir ju ganska kluddigt att hålla på och kolla om det är skottår och liknande.

Medlem sedan aug. 2000374 inlägg
#9

kobranturre skrev:

Koden fungerar iaf inte
/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})/

Jag missade sekunderna, bättre?

<?php

if ( validate_datetime("2004-08-18 12:35:00") ) {
    echo "Goodie!\n";
}

function validate_datetime($date) {
    
    if ( preg_match("/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $date, $matches ) ) {
            
        #year
        if ( !( $matches[1] >= 1900 and $matches[1] <= 2199 ) ) {
            return false;
        }

        #month
        if ( !( $matches[2] >= 1 and $matches[2] <= 12 ) ) {
            return false;
        }

        #day
        if ( !( $matches[3] >= 1 and $matches[3] <= 31 ) ) {
            return false;
        }
        
        #hour
        if ( !( $matches[4] >= 1 and $matches[4] <= 24 ) ) {
            return false;
        }        

        #minute
        if ( !( $matches[5] >= 0 and $matches[5] <= 59 ) ) {
            return false;
        }
        
        #second
        if ( !( $matches[6] >= 0 and $matches[6] <= 59 ) ) {
            return false;
        }
        
        #check date
        if ( !( checkdate( $matches[2], $matches[3], $matches[1] ) ) ) {
            return false;
        }
        
        return true;
    }

    return false;
}

?>
Medlem sedan maj 2004693 inlägg
#10

Hansen skrev:

kobranturre skrev:

Koden fungerar iaf inte
/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})/

Jag missade sekunderna, bättre?

<?php

if ( validate_datetime("2004-08-18 12:35:00") ) {
    echo "Goodie!\n";
}

function validate_datetime($date) {
    
    if ( preg_match("/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $date, $matches ) ) {
            
        #year
        if ( !( $matches[1] >= 1900 and $matches[1] <= 2199 ) ) {
            return false;
        }

        #month
        if ( !( $matches[2] >= 1 and $matches[2] <= 12 ) ) {
            return false;
        }

        #day
        if ( !( $matches[3] >= 1 and $matches[3] <= 31 ) ) {
            return false;
        }
        
        #hour
        if ( !( $matches[4] >= 1 and $matches[4] <= 24 ) ) {
            return false;
        }        

        #minute
        if ( !( $matches[5] >= 0 and $matches[5] <= 59 ) ) {
            return false;
        }
        
        #second
        if ( !( $matches[6] >= 0 and $matches[6] <= 59 ) ) {
            return false;
        }
        
        #check date
        if ( !( checkdate( $matches[2], $matches[3], $matches[1] ) ) ) {
            return false;
        }
        
        return true;
    }

    return false;
}

?>

haha...jooo :)

Medlem sedan maj 2004693 inlägg
#11

föresten hoppas du inte tog illa upp Hansen. Inget illa menat

Medlem sedan aug. 2000374 inlägg
#12

Verkade som jag klantade till mig ;).

Jag valde citera istället för att redigera, kommande inlägg det rätta!

Medlem sedan aug. 2000374 inlägg
#13

Erik Juhlin skrev:

Förresten har inte PHP något inbyggt för att kolla sånt här?
Blir ju ganska kluddigt att hålla på och kolla om det är skottår och liknande.

Det var snack om att införa strptime funktionen från libc, men den har inte dykt upp än :(

kobranturre skrev:

föresten hoppas du inte tog illa upp Hansen. Inget illa menat

Det gjorde jag inte :)

redigering: Jag råkade länka strptime till strftime.

Medlem sedan maj 2004693 inlägg
#14

det där med skottår är faktiskt inte så svår o fixa

använd dig av split på hela strängen..splitta vid -

http://se.php.net/split

sedan så gör du tex $resultat = årtalet/4

använd dig sedan av gettype()

http://se.php.net/gettype

och kolla om talet är heltal eller flyttal. Om $resultat = "integer" så är det skottår :)

edit: Jag skrev fel...det skulle vara / och inte %

Medlem sedan aug. 2000374 inlägg
#15

kobranturre skrev:

det där med skottår är faktiskt inte så svår o fixa

function is_leap($year) {
    if ( ( $year % 400 ) == 0 ) { return true; }
    if ( ( $year % 100 ) == 0 ) { return false; }
    if ( ( $year % 4 ) == 0 ) { return true; }
    return false;
}

Eller så är man lat som jag och använder checkdate funktionen för att validera datum.

Medlem sedan okt. 2001538 inlägg
#16

Tack allihop, inte trodde jag väl att detta skulle bli en sådan jättediskussion :) Koden ovan funkade utmärkt, jag ändrade dock på timmarna så att den kan vara noll, och bara upp till 23 (tycker 00:00:00 ser snyggare ut än 24:00:00)

Många tack för suverän insats.
MVH Patrik

Medlem sedan feb. 20034 441 inlägg
#17

Snor den här tråden för jag har ett liknande problem.

Använder följade för att validera datum (yyyy-mm-dd):

if(!isset($invoice_date) || !preg_match("/^(19|20)[0-9]{2}[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])$/", $invoice_date, $iD)){
	$error[] = "Du angav inte ett giltigt fakturadatum";
}

Men den godtar t.ex. inte "2009-01-01".
Vad är fel i mönstret ovan?

Tack!

269 ms totalt · 4 externa anrop · v20260731065814-full.2f471f9e
128 ms — deklarationer (db)
0 ms — hämta statistik (cache)
136 ms — hämta tråd, inlägg och bilagor (db)
130 ms — ändringar (db)