Just nu i M3-nätverket
Jump to content

Regexp tycker inte om mig


TicoRoman

Recommended Posts

Nu har jag slitit i en hel timme med en simpel regexp-uttryck, men inte vill det fungera bara för det. :(

 

[boja=#ff0000]

ska bli

<font color="#ff0000">

 

Har kommit så här "långt":

$string = "[boja=#ff0000]";

$pattern = "/[[]+boja=/";

$replacement = "<font color=\"";

print preg_replace($pattern, $replacement, $string);

 

:(

 

Kämpar vidare....

 

Just det ja, jag måste ha en funktion som kör det hela åt andra hållet också.

 

_________

TicoRoman - The One And Only

 

 

 

[inlägget ändrat 2003-02-10 01:23:03 av TicoRoman]

[inlägget ändrat 2003-02-10 01:28:16 av TicoRoman]

Link to comment
Share on other sites

Hur generellt ska uttrycket vara? Om du bara vill kapa bort det som kommer innan #-tecknet så är det väl enklare att köra med nån substring-funktion?

 

Link to comment
Share on other sites

Nej, det är jäkla jobbigt med regexp om man inte kan det, jag är själv långt ifrån en expert på det, och försöker verkligen lära mig det bättre....

 

Detta bör fungera:

 

<?php
$string = "[boja=#ff0000]Foo[/boja]bar";

$regexp = array("/\[boja\=(#[0-9A-Fa-f]{6})\]/", "/\[\/boja\]/");
$replace = array("<font color=\"\\1\">", "</font>");

$string = preg_replace($regexp, $replace, $string);

echo $string;
?>

 

--

Some say I am crazy.. but the Voices in my head disagree...

 

Link to comment
Share on other sites

Bj0rns uttryck fungerar säkerligen utmärkt, men jag antar att denna indata kommer från besökare?

Besökare är ofta otroligt dumma (!) vilket är vida känt, och brukar lyckas fylla i indata på alla möjliga olika sätt.

Det kan därför vara bra att på något sätt försöka vidga uttrycket, så att det fungerar även om besökaren klantar till det (med exempelvis stora och små bokstäver, eller onödiga mellanslag).

 

Så här kan de två uttrycken då se ut:

"/\[[[:space:]]*boja[[:space:]]*\=[[:space:]]*\"?(#[0-9a-f]{6})\"?[[:space:]]*\]/i" (notera i:et i slutet, som gör strängen skiftlägesokänslig)

"/\[[[:space:]]*\/[[:space:]]*boja[[:space:]]*\]/i"

 

Några småtips bara...

 

Link to comment
Share on other sites

Nu har jag slitit i en hel timme med en simpel regexp-uttryck(...)
Inga reguljära uttryck är enkla ;) Det ligger i dess natur att vara svåra...

Just det ja, jag måste ha en funktion som kör det hela åt andra hållet också.
Jag föreslår att du istället sparar original-indatan, med []-märkuppsyntaxen, istället för den med <font>, och omvandlar vid utskrift, eller cachar den omvandlade i en separat tabell.

 

En sak till du ska tänka på är att se till att du inte tillåter <syntax> i din indata. Antingen omvandlar du alla < och > till &lt; resp. &gt; innan du gör om [] till <>, elelr så tar du bort dessa taggar med strip_tags().

 

 

Link to comment
Share on other sites

Helt rätt, men å andra sidan tycker jag nog att det ska fungera som det gör här på Eforum, skriver man fel så blir det fel. Lite måste användaren anstränga sig för att få till det rätt! :)

 

Det där med att man ska kunna ha space innan och efter boja tycker jag är overkill, det är ett syntaxfel från användaren, och ska därmed inte tolkas rätt IMHO.

 

Oj vad hård jag är mot mina användare, men jag tycker faktiskt att det ska vara så, rätt ska vara rätt, en användare, även om han är dum får helt enkelt lära sig lite (läsa hur man gör), annars har användaren ingen rätt att vara på mina sidor.

 

OBS: detta är bara mina åsikter om dumma användare, det är ju inte alls säkert att Almir ser på saken på samma sätt som jag. Ditt inlägg har såklart betydelse och är bra för oss som vill lära sig regular expressions bättre.

 

--

Some say I am crazy.. but the Voices in my head disagree...

 

Link to comment
Share on other sites

(...) rätt ska vara rätt, en användare, även om han är dum får helt enkelt lära sig lite (läsa hur man gör), annars har användaren ingen rätt att vara på mina sidor.
Haha! Det var det roligaste jag läst på länge angående webbplatser.

Jag vill gärna hålla med dig, och även tvinga besökarna att använda fungerande webbläsare (dvs. inte Netscape 6 exempelvis), men tyvärr så fungerar inte det i slutändan. Det kommer alltid finnas personer som inte förstår hur saker och ting ska gå till, och samma personer brukar oftas även inte orka läsa eventuell hjälp, utan lyfter direkt på telefonen och ringer utvecklaren/supporten.

 

70% av en webbapplikationsutvecklares (långt ord) tid går åt till felhantering och syntaxformatering av indata, och till korrigeringskod som skriver ut olika saker beroende på besökarens webbläsare. Tänk vad mycket tid man skulle spara om man slapp det...

 

Nej, nu ska jag sluta spy galla och återgå till arbetet. Fast det kan ju bli en intressant diskussion... ;)

 

 

Link to comment
Share on other sites

Mm, jag vet precis hur det är i verkligheten, jobbar själv som systemspecialist/systemutvecklare/webutvecklare i IT branschen sedan 96, man måste göra många olika saker för att få saker att fungera som det ska i alla möjliga miljöer. Självklart gör man oxå detta på arbetstid. Mina åsikter rör dock den privata delen av mitt liv:

 

Då jag gör en sida privat så skiter jag faktiskt fullständigt i om användaren är så dum att han använder en browser som inte följer standarder, jag kodar mina sidor så gott det går efter standarder och kollar i senaste IE/NS om det ser bra ut och där får det vara nog.

 

En funktionalitet på en hemsida tycker jag inte ska vara för snäll heller, detta kan skapa problem för utvecklaren i ett senare skede då man upptäcker att den komplicerade lösningen som tar hänsyn till dumma användare hade buggar som inte hade funnits om man gjorde på det sättet så att användaren måste skriva någonting på rätt sätt.

 

Man kanske kan kalla det för en yrkesskada, men jag börjar faktiskt bli innerligt less på dumma användare och dåligt skrivna webläsare. Om inte användaren/webläsaren klarar det som sajten är skriven för så är det upp till användaren att se till att skaffa rätt webläsare/lära sig hur man gör.

 

Oj vad mycket skit jag lär få för detta nu. :)

 

--

Some say I am crazy.. but the Voices in my head disagree...

 

[inlägget ändrat 2003-02-10 11:54:46 av Bj0rN]

Link to comment
Share on other sites

Ska passa på och tacka för svaren. Har inte tid nu att testa, får göra det imorgon.

 

Dock är det så att jag alltid ställer en fråga om regexp, får ett fungerande svar, och sedan har jag ingen aning hur det egentligen fungerar och varför, så att jag får ställa frågor om samma sak hela tiden.

 

Har någon av er tid att förklara detta lite mer, så skulle jag vara tacksamm. ;)

 

Om vi tex tar BjOrNs exempel:

$regexp = array("/\[boja\=(#[0-9A-Fa-f]{6})\]/", "/\[\/boja\]/");

$replace = array("<font color=\"\\1\">", "</font>");

 

$regexp:

Varför har man tex /\ i början? \ innan =. Hur skiljer man åt det som ska ersättas från det som ska vara kvar i strängen?

 

$regexp:

\\1? Kommatecknet?

 

Känns som att det är dags att jag lär mig det här och slutar spama eForum med regexp-frågor. ;)

 

Glöm inte att mina kunskaper är lika med noll när det gäller regexpar... :(

 

_________

TicoRoman - The One And Only

 

 

 

[inlägget ändrat 2003-02-10 22:50:30 av TicoRoman]

Link to comment
Share on other sites

Mm, det är verkligen inte lätt med regexps...

 

Varför har man tex /\ i början? \ innan =. Hur skiljer man åt det som ska ersättas från det som ska vara kvar i strängen?

 

* / startar en regular expression i det här fallet.

* \ visar att nästa tecken är ett tecken som är reserverat i regular expressions, och ska alltså inte tolkas i sin vanliga mening.

 

\\1? Kommatecknet?

 

* \\1 betyder att här ska det första som har blivit ändrat med hjälp av vår regular expression hamna.

* Komma tecknet är en del av arrayen :)

 

Jag är själv ingen expert på regexps, men jag hankar mig fram och försöker läsa mig till att kunna det bättre. Det är svårt.... men oerhört kraftfullt då man väl kan det.

 

--

Some say I am crazy.. but the Voices in my head disagree...

 

Link to comment
Share on other sites

* \\1 betyder att här ska det första som har blivit ändrat med hjälp av vår regular expression hamna.

Hur är det markerat i $regexp vad som ska stå kvar (alltså det hexdecimala numret)?

 

Man har ju följande inom paranteser

(#[0-9A-Fa-f]{6})

så man skulle kunna tänka att det är det som är så att säga kvar, men lika(=)-tecknet är ju lämnat utanför, och den finns även i $replace, så det stämmer nog inte riktigt att det är det inom paraneserna som ä kvar...

 

Link to comment
Share on other sites

Om vi går igenom Bj0rns uttryck, bit för bit, med reservation för att han redan förklarat ovan ;)

 

Uttrycket:

/\[boja\=(#[0-9A-Fa-f]{6})\]/

 

/\[boja\=(#[0-9A-Fa-f]{6})\]/

- Man börjar och slutar ett reguljärt uttryck (RU) med exempelvis ett snedstreck; "/". Man kan även använda "#".

I slutet, alltså efter / (alt. #) kan man sätta en eller flera modifierare. Dessa är vanliga bokstäver, och betyder olika saker. Exempelvis "i" som betyder skiftlägesokänslig (case insensitive), eller "e" som betyder att ersättningssträngen är PHP-kod som ska exekveras.

 

/\[boja\=(#[0-9A-Fa-f]{6})\]/

- Sedan kommer ett [-tecken, men då detta är ett reserverat tecken i RU-syntaxen, så måste man "escapa" det. Detta görs som vanligt med ett bakvänt snedstreck (\). I slutet är det likadant.

 

/\[boja\=(#[0-9A-Fa-f]{6})\]/

- Bokstäver som inte har ett bakvänt snedstreck framför sig räknas som vanliga bokstäver.

 

/\[boja\=(#[0-9A-Fa-f]{6})\]/

- Likamed-tecken är inte en del av RU-syntaxen, och behöver därför inte inledas med \, men som du märker i detta fall så gör det inget om man gör det ändå. Play it safe...

 

/\[boja\=(#[0-9A-Fa-f]{6})\]/

- Sedan kommer en grupp. De omges av paranteser; ().

Man räknar från vänster till höger, och numrerar dessa grupper från 1 och uppåt.

I detta RU finns bara en grupp, som då alltså går att komma åt med \\1.

 

/\[boja\=(#[0-9A-Fa-f]{6})\]/

- Om man sedan delar upp gruppen, så ser vi att det först är ett vanligt tecken "#".

 

/\[boja\=(#[0-9A-Fa-f]{6})\]/

- Efter så kommer en "eller"-sats. Vilket som helst av de tecken som står inom [] kan matcha. I detta fall är det även intervaller, dvs 0-9 (matchar 0,1,2...9), A-F (A,B,C...F), och a-f (a,b,c...f).

Om man vill matcha de svenska bokstäverna å-ö måste man lägga till dessa separat (a-ö fungerar ej). Ett bättre sätt är dock att använda sig av klasser. Exempel på sådana är [[:space:]], [[:digit:]], [[:alnum:]]. Läs mer i manualen om dessa.

 

/\[boja\=(#[0-9A-Fa-f]{6})\]/

- Till sist kommer {6}, vilket betyder att det måste matcha 6 tecken i följd ur gruppen ovan (eller-satsen). Man kan skriva {,6} vilket betyder >= 0 och <= 6, {6,} som betyder minst 6 tecken, eller exempelvis {2,6} som betyder => 2 och <= 6.

 

Pust! Hoppas nåt gick in! ;)

 

Link to comment
Share on other sites

(#[0-9A-Fa-f]{6})

 

Det inom parentes är den biten som \\1 ska visa upp, dvs ett staket följt av siffror eller små/stora bokstäver från a till f. Dessa tecken efter staketet ska inte vara fler än 6 stycken. Resten av strängen ska helt enkelt bytas ut mot det som finns i $replace.

 

[boja= blir: <font color="

#ff0000 blir: #ff0000

] blir: ">

 

[/boja] blir: </font>

 

--

Some say I am crazy.. but the Voices in my head disagree...

 

Link to comment
Share on other sites

I preg_replace() så ersätts hela uttrycket som matchar, med det som kommer i argument 2.

 

Exempel 1:

$str = "Allt har blivit öde, man får cancer utav sol."
echo preg_replace("/ man får/i", "", $str);

Skriver ut "Allt har blivit öde, cancer utav sol.".

 

Exempel 2 (med en grupp):

$str = "Allt har blivit öde, man får cancer utav sol."
echo preg_replace("/ man (får)/i", " \\1 inte", $str);

Skriver ut "Allt har blivit öde, får inte cancer utav sol.".

 

Exempel 2 (lite mer avancerat):

$str = "Allt har blivit öde, man får cancer utav sol."
echo preg_replace("/ man får (.*)\./i", " får man \\1?", $str);

Skriver ut "Allt har blivit öde, får man cancer utav sol?".

 

 

Link to comment
Share on other sites

Pust! Hoppas nåt gick in! ;)
Jodå jag förstod mycket.

 

Jag har dock hakat upp mig på lika-tecknet. Alltså:

 

/\[boja\=(#[0-9A-Fa-f]{6})\]/

 

Den står ju utanför "gruppen". Som sagt kommer man åt det stom står i gruppen, dvs paranteserna med \\1. Detta borde väl bara "markera" tex #FF0000.

 

I $replace så har man:

 

"<font color=\"\\1\">"

 

som enligt det lilla som jag förstår borde ge:

 

<font color="#FF0000">

 

vilket är ju precis som det ska vara. Hahahah förlåt, jag tänkte fel tydligen. Fick för mig att det skulle bli == i font-taggen. Sorry...

 

Om vi sedan fortsätter: (bekräfta bara om jag har rätt)

 

array("/\[boja\=(#[0-9A-Fa-f]{6})\]/", "/\[\/boja\]/")

 

kommer ju ge en array med två hmm vad man ska kalla dem, "grejer" i sig. alltså $regexp[0] och $regexp[1].

 

Hmm jag tror att jag förstått det här nu!! Får testa med några egna tuffa regexpar när jag får tid.

 

Det som jag har kvar att lära mig är hur man gör när man tex söker efter ett visst mönster i en text, säg tex email-adresser och lägger dessa i en array.

 

Fast när jag tänker efter så tror jag att jag fick ett liknande exempel tidigare här på eForum. Ska leta...

 

Hursomelst så ser jag att detta inlägg blev onödigt långt och tråkig, men jag förstod i alla fall medan jag skrev. ;)

 

 

 

_________

TicoRoman - The One And Only

 

[inlägget ändrat 2003-02-10 23:41:02 av TicoRoman]

Link to comment
Share on other sites

Jag förstod i stort sett allt, förutom Cariads Exempel 2 (lite mer avancerat), som jag inte fattade helt, men detta är överkurs för mig just nu, så det lämnar vi.

 

Hursomhelst så tänkte jag bara säga att jag hoppas att ni inser hur tacksamm jag är för alla svar jag fått i just PHP-forumet. För ca 4-5 månader sedan var jag helt nybörjare på PHP. Sedan dess har jag lärt mig väldigt mycket (tror jag), och även hjälpt till andra användare en hel del med just PHP.

 

Det mesta har jag lärt mig från manualen, samt här på eForum. De som oftast svara på mina frågor här är just ni två, Cariad och BjOrN. Ännu en gång tack för att ni finns, och tack även till alla andra som någon gång svarat. ;)

 

 

 

_________

TicoRoman - The One And Only

 

[inlägget ändrat 2003-02-10 23:50:05 av TicoRoman]

Link to comment
Share on other sites

I det andra exemplet som Cariad skrev:

 

$str = "Allt har blivit öde, man får cancer utav sol."

echo preg_replace("/ man (får)/i", " \\1 inte", $str);

 

är det gruppen som hänger med och sätts in där \\1 står. "man" försvinner. "man får" ersätts alltså med "får inte"

 

En liten grej som jag brukar rätta mig efter:

 

Man är alltid nybörjare från början, man lär sig av sina misstag samt av hjälp från andra och genom att hjälpa andra.

 

Med detta menar jag att man lär sig mycket genom att hjälpa andra och att bli hjälpt eftersom man kanske hittar något nytt sätt att lösa en sak på. Ibland kan det nya sättet vara bättre än det sättet man själv har löst det på tidigare. (hrrmm, nu är jag trött, fattar inte vad jag själv skrev...)

 

Själv hjälper jag gärna till om jag kan någonting, i gengäld hoppas jag att någon kan svara på mina frågor om jag har några.

 

--

Some say I am crazy.. but the Voices in my head disagree...

 

Link to comment
Share on other sites

Bara helt apropå....

 

Allt har blivit öde, man får cancer utav sol.

 

Intressant... Undrar varför det blev just det som exempelsträng?

 

Nej, nu ska jag nog lägga mig, kom hem för nån timma sen från jobbet och ska upp tidigt imorrn för att fortsätta... inget roligt med releaser då man inte riktigt är klar i tid...

 

--

Some say I am crazy.. but the Voices in my head disagree...

 

[inlägget ändrat 2003-02-11 00:09:49 av Bj0rN]

Link to comment
Share on other sites

I det andra exemplet som Cariad skrev
Nej, det var alltså det tredje exemplet jag menade, men som felaktigt blev 2. Alltså:
$str = "Allt har blivit öde, man får cancer utav sol."
echo preg_replace("/ man får (.*)\./i", " får man \\1?", $str);

Vad betyder stjärnan i (.*)?

 

hrrmm, nu är jag trött, fattar inte vad jag själv skrev
Jodå, jag fattar vad du skrev. Det är bra (=tur) att man hjälper varandra. :)

 

 

_________

TicoRoman - The One And Only

 

Link to comment
Share on other sites

Vad betyder stjärnan i (.*)?

Punkten (.) betyder "vilket tecken som helst", asterisken (*) står för antalet tecken att matcha, och betyder 0 eller hur många som helst.

 

Alltså (.*) betyder "matcha alla tecken, och hur många som helst!". Ganska aggresivt alltså... ;)

 

Link to comment
Share on other sites

Aha, så ("/ man får (.*)\./i betyder alltså att det som ska "matchas", lr bli \\1 är allt mellan får mellanslag och punkt. \. eftersom . är ett reserverat tecken liksom tex [.

 

Mm nu har jag fattat det här. ;)

 

Tack!

 

 

_________

TicoRoman - The One And Only

 

Link to comment
Share on other sites

Sehr gut!

 

Nu är det dags för lite sömn, för min del. Tack igen för hjälpen!

 

 

_________

TicoRoman - The One And Only

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.



×
×
  • Create New...