[PHP] Eigen trim() met Regex

Pagina: 1
Acties:
  • 317 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • sjaakie
  • Registratie: Oktober 2000
  • Niet online

sjaakie

Developer

Topicstarter
Het volgende is het geval.

Ik heb een soort rapport bestand waarin een aantal variabellen staan aangeduidt en wel op de volgende manier:

code:
1
uf(<%voornaam%>)trim( <%tussenvoegsel%> )uf(<%achternaam%>)


Het idee is nu dat als de var "<%tussenvoegsel%>" leeg is er niks komt te staan (is null waarde nm) en worden de extra spaties weg "getrimmed".

Als hij dus wel gevuld is zou er dus wel één spatie mogen staan aan het begin en aan het einde.

Ik hebal verschillende regex tuts doorlopen maar ik kom er niet uit. Is er iemand die me een eindje op weg kan helpen?

Edit: het gaat dus puur over de trim functie, het replacen van die variabellen is reeds gelukt.

[ Voor 20% gewijzigd door sjaakie op 25-05-2006 22:55 ]

Als je enige gereedschap een hamer is, ziet elk probleem eruit als een spijker...


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Met preg_replace_callback(). :)
PHP:
1
2
3
4
5
function trim_callback($matches) {
  return trim($matches[1]);
}

$tekst = preg_replace_callback("/trim\(([^)]*)\)/Ui", "trim_callback", $tekst);

edit:
Dit doet natuurlijk niet precies wat jij wil, maar die callback-functie kun je zelf ook gewoon aanpassen. ;)

[ Voor 21% gewijzigd door NMe op 26-05-2006 00:05 ]

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

Verwijderd

Geen idee wat 'uf' doet, maar waarom zou je hier een regex voor nodig hebben?
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
string Fullname(string voornaam, string tussenvoegsel, string achternaam)
{
  string result = voornaam;
  if (tussenvoegsel != "")
  {
    if (result != "") { result += " "; }
    result += tussenvoegsel;
  }
  if (achternaam != "")
  {
    if (result != "") { result += " "; }
    result += achternaam;
  }
  return result;
}
Omzetten naar php functie is een eitje, denk ik... :)

[ Voor 10% gewijzigd door Verwijderd op 26-05-2006 22:20 ]


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Hij zegt toch dat hij een bepaald bestand uitleest in dat formaat? Hij zal dus sowieso dat formaat om moeten gaan zetten naar variabelen. En of je nou zijn aanpak neemt (de originele string pakken en daar het overbodige uitknippen) of jouw aanpak (alle zinvolle stukken uit de originele zin aan elkaar plakken) maakt verder wat betreft performance niet zo uit.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

Verwijderd

Qua performance niet, qua leesbaarheid en onderhoudbaarheid wel degelijk.
Ik ben echt geen beginnende ontwikkelaar, en ook wel vertrouwd met regexes, maar bij jouw oplossing moet ik de regex toch eerst 3x lezen voordat ik weet wat 'ie doet. Mijn oplossing is onderhoudbaar door iedere beginnende ontwikkelaar.

Acties:
  • 0 Henk 'm!

  • BtM909
  • Registratie: Juni 2000
  • Niet online

BtM909

Watch out Guys...

Verwijderd schreef op vrijdag 26 mei 2006 @ 22:31:
[...] maar bij jouw oplossing moet ik de regex toch eerst 3x lezen voordat ik weet wat 'ie doet. [...]
Ligt dat aan jou of aan de code? ;)

Ace of Base vs Charli XCX - All That She Boom Claps (RMT) | Clean Bandit vs Galantis - I'd Rather Be You (RMT)
You've moved up on my notch-list. You have 1 notch
I have a black belt in Kung Flu.


Acties:
  • 0 Henk 'm!

Verwijderd

Ligt aan mij natuurlijk (ben geen regex guru, en moet die dingen vaak meer dan 3x lezen), maar vooral aan het gebrek aan commentaar/uitleg in -NMe-'s oplossing.
Zijn oplossing kan geniaal zijn, maar niemand weet zonder er echt in te duiken waarom.
Mijn oplossing doet 't ook gewoon prima, en ik hoef niemand uit te leggen waarom. ;)

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Afterlife, jouw oplossing heeft alsnog óók een regexp nodig* om het zaakje uit te lezen, en ik vermoed dat die een stuk ingewikkelder uit zou zijn dan wat ik hierboven in elkaar gezet heb. ;)

* Zelf parsen kan ook natuurlijk, maar dan is een regexp net even iets efficiënter.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

Verwijderd

Volgens TS is 't parsen van de variabelen al gelukt, dus wat is dan de meerwaarde van een regex?
Efficientie? Ja, je wint er misschien een paar milliseconden mee. Maar dan wel gedocumenteerd, zodat mede-ontwikkelaars ook direct weten wat 't ding doet.
Een simpel functietje dat 't ook doet is dan misschien toch handiger... ;)

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Hij zegt dat het replacen is gelukt, niet dat ie elke variabele los heeft gehaald. ;)

En natuurlijk documenteer je zoiets wel, maar dat vond ik hier even niet nodig. Ik bood een oplossing, geen kant en klaar gedocumenteerd stuk code. Sowieso is het een erg eenvoudige regexp die zichzelf verklaart IMO.
edit:
@hieronder:
Damn! Wil je dan altijd gelijk hebben? :+
Uhuh. :+

[ Voor 12% gewijzigd door NMe op 26-05-2006 23:53 ]

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

Verwijderd

Damn! Wil je dan altijd gelijk hebben? :+
Als je variabelen (met 1 of meer 'l'en) kunt replacen, heb je ze al losgehaald.
En IMO bestaat er niet iets als een self explaining regex. :P

@hierboven:
Voor deze keer dan... :>

[ Voor 22% gewijzigd door Verwijderd op 27-05-2006 00:07 ]


Acties:
  • 0 Henk 'm!

  • sjaakie
  • Registratie: Oktober 2000
  • Niet online

sjaakie

Developer

Topicstarter
Misschien vraagt het om iets meer uitleg.

Het idee is als volgt:

De mensen kunnen zelf rapport bestanden maken. Dat kan bijvoorbeeld een brief zijn, daar kunnen ze dan die variabellen in plakken. Alleen ik moet wel bijvoorbeeld af kunnen dwingen dat een naam met een hoofdletter begint. Ik wil liever niet de rapport bestanden door een eval() halen, om hacks te voorkomen. Dus heb een een paar custom/alias functies bedacht (uf=ucfirst, up=strtoupper(), low=strtolower()) om toch voor elkaar te krijgen dat die string bewerkingen kunnen worden uitgevoerd.

De laatste die ik dus nog nodig had is de trim() functie, en daar heb ik jullie hulp ff bij nodig.

Als je enige gereedschap een hamer is, ziet elk probleem eruit als een spijker...


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Goed hoor, maar voldoen geen van de oplossingen hierboven?

Geef in dat geval eens een voorbeeld van wat er precies in dat bestand staat, en wat je precies voor bewerking daarop verwacht.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • sjaakie
  • Registratie: Oktober 2000
  • Niet online

sjaakie

Developer

Topicstarter
Ok een onderstaand stuk tekst zou zo'n sjabloon/rapport kunnen zijn. Het wordt uiteindelijk een .csv file. Daarom de ";" voor de kolomscheiding.

code:
1
2
header=Voornaam;Achternaam;
rows=uf(<%voornaam%>);trim( <%tussenvoegsel%> )uf(<%achternaam%>);

Ik maakte zelf ff de denkfout dat trim( <%tussenvoegsel%> ) één spatie zou laten staan. Redelijk stom |:(
code:
1
2
header=Voornaam;Achternaam;
rows=uf(<%voornaam%>);trim(<%tussenvoegsel%> uf(<%achternaam%>));

In die zin is bovenstaande dus de manier die ik eigenlijk zoek. Om te voorkomen dat als er geen tussenvoegsel is de string niet begint met een spatie. Als er wel een tussenvoegsel is staat die middenin, dus wordt hij ook niet "getrimmed".

Zo zie je maar weer, soms heb je wel eens last van een programmersblock ;).

Ben benieuwd of dit op te lossen is met een regex, maar als mensen een beter idee hebben dan hou ik me aanbevolen. Ben er zelf ook nog niet helemaal uit of dit DE oplossing is.

De oplossing van -NMe- is dus een begin, alleen nog niet helemaal compleet volgens mij.

Als je enige gereedschap een hamer is, ziet elk probleem eruit als een spijker...


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Tsja, je gaat nu haakjes nesten, en vanaf dat moment worden regular expressions ineens erg lastig. Het kan vast wel als je lookaheads of lookbehinds gebruikt, maar eigenlijk is het veel handiger om in dit geval de zaak toch maar handmatig te gaan parsen. Dat houdt in dat je alles zelf moet gaan tokenizen en dat gaat het eenvoudigste middels een stackbased parser.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

Verwijderd

Jeez! Hoe moeilijk is 't nou om 3 strings (voornaam, tussenvoegsel, achternaam) samen te voegen tot 1 string, met een spatie tussen de onderdelen?
Wil je iets meer dan dat, dan wordt 't idd tokenizen en een stackbased parser maken.
Niks mis mee, en je kunt dan vrij eenvoudig if / else, switch / case, en loop dingen toevoegen, maar zo'n parser schrijf je niet in een verloren uurtje.En regular expressions zijn dan niet echt bruikbaar.

Acties:
  • 0 Henk 'm!

  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
Verwijderd schreef op zaterdag 27 mei 2006 @ 23:15:
Niks mis mee, en je kunt dan vrij eenvoudig if / else, switch / case, en loop dingen toevoegen, maar zo'n parser schrijf je niet in een verloren uurtje.
Met een simpele state machine kom je toch al een aardig eindje, hoor :).
En regular expressions zijn dan niet echt bruikbaar.
Juist wel! Tenminste voor het 'normale' parse werk; ze zijn een stuk makkelijker te volgen als, pak 'm beet, 100 regels PHP code met hetzelfde doel. (Minder variabelen, minder kans op fouten, minder grote brei, en het zit een stuk logischer in elkaar).
Pagina: 1