Gå til innhold

Regulært uttrykk vha. eregi i php


Anbefalte innlegg

Hallo.

 

Jeg sitter og svetter litt over en oblig i php. Oppgaven er som følger:

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

Lag et regulært uttrykk (Regex) som vha. eregi() skal gi verdien 1 (sann) når teksten den gis inneholder et tall. Tallene kan se slik ut:

 

1

 

2.7818

 

3.1415E4 eller 3.1415E-4

 

Skriv regex’en som matcher alle tallmønstrene.

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

 

 

Jeg har kommet så langt at jeg har laget en enkel variant som skjønner at det er snakk om et enkelt tall, verken mer eller mindre, men sliter med fortsettelsen.

 

Det jeg lurer på er hvordan man kan si at det etter dette tallet kan være, eller ikke være, et punktum, og at det kan være eller ikke være en ny rekke med tall fra [0-9] samt null eller flere bokstaver fra [A-F].

 

Det er vel et regulært uttrykk for flyttall, tror jeg da, det er snakk om her.

 

 

Jeg vil ikke at noen skal gjøre leksene for meg, men jeg har virkelig kjørt meg helt fast og trenger litt input.

 

Det lille jeg har fått til så langt:

 

<?php

$tallet= '2';

 

 

if (eregi('^[0-9]{1,1}$', $tallet))

{

echo '1';

}

?>

 

Det er altså det å få inn i uttrykket at strengen har en opsjon for et punktum, og de videre tallene (HEX).

 

Jeg har tittet på en del guider, men klarer ikke å skjønne utfra dem hvordan jeg skal løse akkurat dette problemet.

 

Takknemlig for alle tilbakemeldinger!

 

Almeraldo

Lenke til kommentar
Videoannonse
Annonse

\. tilsvarer å finne et punktun i en streng \d et tall. + betyr å finne 1 eller flere.

 

Dermed vil typisk \d+\.\d+ godta 4.5 og 8346732.23472398479832

 

Dette matcher da ikke den siste muligheten din, men det er samme systemet, når du kan bruke +, * og ? er du et stykke på vei. Har ikke noen god regex-guide for hånden, men du kan jo titte litt her:

 

http://en.wikipedia.org/wiki/Regular_expressions

 

og

 

http://www.regular-expressions.info/reference.html

 

og

 

http://www.greenend.org.uk/rjk/2002/06/regexp.html

 

og se om du får noe mer ut av dette! Kan godt hjelpe deg enda mer på vei, men det er kanskje ikke det du vil?

Lenke til kommentar

Jeg har ikke noe peiling på POSIX-motoren (eregi()), men denne fungerer ihvertfall 100% på Perl-motoren (preg_match()).

^[0-9](\.[0-9]+(E-?[0-9]+)?)?$

Du kan kanskje se litt på den og få litt idéer om hva du må gjøre.

 

Edit: En liten feil, og en liten forenkling.

Endret av endrebjorsvik
Lenke til kommentar
\. tilsvarer å finne et punktun i en streng \d et tall. + betyr å finne 1 eller flere.

 

Dermed vil typisk \d+\.\d+ godta 4.5 og 8346732.23472398479832

 

Dette matcher da ikke den siste muligheten din, men det er samme systemet, når du kan bruke +, * og ? er du et stykke på vei. Har ikke noen god regex-guide for hånden, men du kan jo titte litt her:

 

http://en.wikipedia.org/wiki/Regular_expressions

 

og

 

http://www.regular-expressions.info/reference.html

 

og

 

http://www.greenend.org.uk/rjk/2002/06/regexp.html

 

og se om du får noe mer ut av dette! Kan godt hjelpe deg enda mer på vei, men det er kanskje ikke det du vil?

8203408[/snapback]

 

Takk for bra svar!

 

Jeg stiller sikkert dumme spørsmål nå, men hvordan blir uttrykket ditt seende i praksis? Altså inne i selve eregi()?

 

 

Jeg prøvde å teste det på denne måten:

 

 

eregi('\d+\.\d+', $streng)

 

Det funket ikke så da er det vel noe jeg har gjort galt med syntaksen. Jeg er helt grønn på dette ... Jeg blir ikke såret og lei meg om du demonstrerer hvordan det endelige uttrykket blir seende ut inne i eregi(), jeg må jo uansett sette meg inn i hvordan det funker.

 

Almeraldo

Lenke til kommentar

\d funker visst ikke med ereg(), men kan brukes med preg_match().

Er diverse små forskjeller på POSIX-regex og Perl-regex.

 

Svaret blir feks slik:

$result = eregi('[0-9]+(\.[0-9]+(E-?[0-9]+)?)?', $streng);

 

Men merk at den vil returnere 1 hvis den finner det tallet ett eller annet sted i strengen. Så hvis $streng er "2134.E9", så får du fortsatt 1, siden den matcher "2134".

 

Hvis du driver å tester, så kan det være greit å ha eregi('^regex_her$', $var). ^ markerer da starten på strengen, og $ slutten, slik at hele $var må matche regexen.

Lenke til kommentar
\d funker visst ikke med ereg(), men kan brukes med preg_match().

Er diverse små forskjeller på POSIX-regex og Perl-regex.

 

Svaret blir feks slik:

$result = eregi('[0-9]+(\.[0-9]+(E-?[0-9]+)?)?', $streng);

 

Men merk at den vil returnere 1 hvis den finner det tallet ett eller annet sted i strengen. Så hvis $streng er "2134.E9", så får du fortsatt 1, siden den matcher "2134".

 

Hvis du driver å tester, så kan det være greit å ha eregi('^regex_her$', $var). ^ markerer da starten på strengen, og $ slutten, slik at hele $var må matche regexen.

8206640[/snapback]

 

 

Takk for svaret! Dette ser veldig nære ut, men sånn som jeg oppfatter oppgaveteksten så er det snakk om at den også skal kunne catche hexadecimale tall, med innslag av A-F, såvidt jeg kan tyde utfra det du laget så tar den bare E. Et annet poeng, tror jeg da, er at det før punktum bare skal kunne være et siffer. Så regex'en må altså matche:

 

1 stk siffer som enten står alene, eller er fulgt av et punktum, og som igjen kan være fulgt av 1 eller flere siffer og at det er åpning for bruk av det hexadecimale tallsystemet.

 

Det er mulig jeg er litt på jordet nå, men det er slik jeg leser oppgaveteksten. Sånn ser eregi() ut hos meg etter at jeg brukte ditt forslag:

 

if (eregi('^[0-9]{1,1}+(\.[0-9]+(E-?[0-9]+)?)?$',$tallet))

{

echo '1';

}

?>

 

Jeg har som du ser lagt til {1,1} for at den ikke skal tolerere mer enn ett siffer før punktum.

 

 

Uansett tusen takk for veldig bra svar!

 

 

 

Almeraldo

Endret av almeraldo
Lenke til kommentar
Nah, E-en er for "vitenskaplig notasjon".

2.343E5 betyr 2,343 * 10^5

 

Men du har rett i at det bare skal være ett tall foran komma. Men i stedet for {1,1} kan du la være å skrive noe som helst, så vil den måtte matches én gang. Altså eregi('[0-9](\.[0-9]+(E-?[0-9]+)?)?', $streng);

8207586[/snapback]

 

 

Ah, tusen takk! Du/dere har helt rett, nå funker det også. Jeg er meget takknemlig for hjelpen.

 

Det eneste som kunne toppet dette er om en av dere kunne tenke seg å brekke opp resultatet i biter og forklare syntaksen. Jeg sliter bitte litt med å f.eks skjønne hvor et spørsmålstegn må plasseres for at det skal fungere slik at det foran blir valgfritt, etc ...

 

 

Almeraldo

Lenke til kommentar

Skaff deg en editor med syntax-highlighting, så ser du hvilke parenteser som hører til hverandre.

(\.[0-9]+(E-?[0-9]+)?)?: Denne parentesen og spørsmålstegnet gjør .0123 (og .0123E-2) valgfritt.

(E-?[0-9]+)?: Gjør E2 eller E-3 valgfritt.

-?: Gjør minustegnet valgfritt.

 

Vanligvis gjør spørsmålstegnet kun det venstreliggende tegnet valgfritt, men hvis vi samler ting sammen i en parentes, vil spørsmålstegnet styre hele parentesen til venstre.

Og så må vi bare nøste parentesene sammen på en logisk måte.

Endret av endrebjorsvik
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...