Avatar billede learner Praktikant
03. maj 2011 - 12:26 Der er 21 kommentarer og
1 løsning

fjerne tegn i slutning af streng ved hjælp af preg_replace()

Jeg har brug for hjælp med at fjerne M hvis det står i slutningen af linjen. Helst ved hjælp af preg_replace()

Denne fjerner M'et fint med tager også M'et i Med.

<?php
$str = 'Trøje Med Tryk M';
$str = preg_replace('/ M/', '', $str);
echo $str;
?>

Kan jeg få den til kun at fjerne M hvis det står som sidste bogstav. Fx ved at skrive "/ M\s-/" eller noget ?

På forhånd tak
Avatar billede repox Seniormester
03. maj 2011 - 12:33 #1
Det vil være væsentligt bedre at undgå at bruge regular expressions til så små formål.

En løsning kunne være

if( strtolower(substr($str, -1)) == "m" )
  $str = substr($str, 0, -1);
Avatar billede erikjacobsen Ekspert
03. maj 2011 - 12:42 #2
Du kan prøve:

$str = preg_replace('/ M$/', '', $str);
Avatar billede repox Seniormester
03. maj 2011 - 12:49 #3
#2
Jeg troede faktisk du ville være en af de første til at fraråde brugen af reg exp til så små ting? :)

Tager jeg fejl eller er den gængse opfattelse ikke at reg exp er 'tungt' og hvis opgaverne er små nok, så er det bedre at undgå det?
Avatar billede learner Praktikant
03. maj 2011 - 13:01 #4
repox jo det er også lidt mere kompleks den bruges, men jeg har forenklet det for at gøre det lettere for Jer at hjælpe mig :o)

erik din løsning fungerer :o) smid svar tak
Avatar billede erikjacobsen Ekspert
03. maj 2011 - 13:01 #5
"Bedre" .... ud fra hvilke kriterier?
Avatar billede repox Seniormester
03. maj 2011 - 13:08 #6
#2
Kriteriet var at reg exp er (påstået) tungere end PHP's generelle streng-funktioner. Det er jeg blevet tudet ørerne fulde af flere gange - ikke kun her på eksperten.dk men også på andre fora.
Avatar billede repox Seniormester
03. maj 2011 - 13:10 #7
Hov... #6 var egentlig til #5 - og jeg vil gerne tilføje et link til SO som en reference for min undren: http://stackoverflow.com/questions/634676/which-is-more-efficient-php-string-functions-or-regex-in-php

Jeg ved godt at der ikke er universelle sandheder, men hvis jeg har mulighed for at lære lidt mere, så er jeg åben...
Avatar billede erikjacobsen Ekspert
03. maj 2011 - 13:15 #8
Jeg tror heller ikke på universelle sandheder ;)

Men lad mig lige anføre et par ting

1)
Vi ved ikke om spørgeren skal udføre en replace hver anden time eller 5000 i sekundet.

2)
Vi ved ikke om din løsning konkret er hurtigere, og i givet fald hvor meget.

3)
Din løsning giver ikke samme resultat som min, så det er som at sammenligne æbler med meteorsten.

4)
Et regulært udtryk er dokumentation i sig selv, og din løsning er hverken bevist korrekt, eller testet korrekt.

... men ja, der kan selvfølgelig være forskellige løsninger på samme problem.
Avatar billede repox Seniormester
03. maj 2011 - 13:21 #9
#8
Point taken :)
Avatar billede erikjacobsen Ekspert
03. maj 2011 - 13:26 #10
;)

5)
Og ja, det vil være forholdsvis nemt at ændre din kode til at fjerne "mellemrum og stort M i slutningen af strengen". Og ja, det kan godt være det er hurtigere.
Avatar billede learner Praktikant
03. maj 2011 - 13:43 #11
jeg skal replace mange gange på alle sidevisninger. Er den da meget langsom den metode? Så vil jeg da gerne vide det og evt have forslag til en anden løsning som kan det samme :o)

her er det komplette jeg bruger:
$title_product_name_remove_patterns[] = '/(\d+),(\d+) kg./i';
$title_product_name_remove_patterns[] = '/(\d+),(\d+) kg/i';
$title_product_name_remove_patterns[] = '/(\d+) kg./i';
$title_product_name_remove_patterns[] = '/(\d+) kg/i';
$title_product_name_remove_patterns[] = '/(\d+)kg./i';
$title_product_name_remove_patterns[] = '/(\d+)kg/i';
$title_product_name_remove_patterns[] = '/(\d+) ml./i';
$title_product_name_remove_patterns[] = '/(\d+) ml/i';
$title_product_name_remove_patterns[] = '/(\d+)ml./i';
$title_product_name_remove_patterns[] = '/(\d+)ml/i';
$title_product_name_remove_patterns[] = '/(\d+) stk./i';
$title_product_name_remove_patterns[] = '/(\d+) stk/i';
$title_product_name_remove_patterns[] = '/(\d+) gr./i';
$title_product_name_remove_patterns[] = '/(\d+) gr/i';
$title_product_name_remove_patterns[] = '/(\d+)gr./i';
$title_product_name_remove_patterns[] = '/(\d+)gr/i';
$title_product_name_remove_patterns[] = '/(\d+) g./i';
$title_product_name_remove_patterns[] = '/(\d+) g/i';
$title_product_name_remove_patterns[] = '/(\d+)g./i';
$title_product_name_remove_patterns[] = '/(\d+)g/i';
$title_product_name_remove_patterns[] = '/(\d+)x(\d+) cm./i';
$title_product_name_remove_patterns[] = '/(\d+)x(\d+) cm/i';
$title_product_name_remove_patterns[] = '/(\d+) cm./i';
$title_product_name_remove_patterns[] = '/(\d+) cm/i';
$title_product_name_remove_patterns[] = '/(\d+)cm./i';
$title_product_name_remove_patterns[] = '/(\d+)cm/i';
$title_product_name_remove_patterns[] = '/(\d+) stk./i';
$title_product_name_remove_patterns[] = '/(\d+) stk/i';
$title_product_name_remove_patterns[] = '/(\d+)stk./i';
$title_product_name_remove_patterns[] = '/(\d+)stk/i';
$title_product_name_remove_patterns[] = '/ XS$/';
$title_product_name_remove_patterns[] = '/ S$/';
$title_product_name_remove_patterns[] = '/ M$/';
$title_product_name_remove_patterns[] = '/ L$/';
$title_product_name_remove_patterns[] = '/ XL$/';
$title_product_name_remove_patterns[] = '/ XXL$/';
$title_product_name_remove_patterns[] = '/ smagsprøve/i';
$title_product_name_remove_patterns[] = '/(\d+) x /i';
$title_product_name_remove_patterns[] = '/(\d+)-(\d+) kilo/i';
$title_product_name_remove_patterns[] = '/med (\d+) pipetter/i';
$title_product_name_remove_patterns[] = '/over (\d+) kilo/i';
$title_product_name_remove_patterns[] = '/(\d+)-(\d+) kg/i';
$title_product_name_remove_patterns[] = '/  /i';
$title_product_name_remove_patterns[] = '/  /i';

$stripped_products_name = trim(preg_replace($title_product_name_remove_patterns, '', trim("Produktnavn Grøn 40x12 cm")));
Avatar billede erikjacobsen Ekspert
03. maj 2011 - 14:11 #12
Det virker voldsomt at gøre det ved hver visning. Hvad med at have et ekstra felt i databasen, så du både har det fulde navn "Produktnavn Grøn 40x12 cm" og kælenavnet "Grøn" - eller hvad det nu bliver til?

Du kan evt. lave den store replace ved oprettelsen af produktet.
Avatar billede learner Praktikant
03. maj 2011 - 14:25 #13
nej det skal helst foregå når siden loader. og det foregår altså rigtig mange gange på nogen sider. men kan det laves samme nummer med en anden funktion, som er hurtigere??
Avatar billede erikjacobsen Ekspert
03. maj 2011 - 14:36 #14
"helst" ?  Du vil helst når siden loader. Dvs du udelukker ikke en anden løsning. Det lyder jo godt.

Men du kan jo prøve at se om det er for langsomt. Hvis ikke, så er der ingen grund til at ændre noget.
Avatar billede learner Praktikant
03. maj 2011 - 15:43 #15
jo men det er en funktion til en webshop. der selv kigger om der er nogen "beslægtede" produkter og så grupperer produkterne.
det er pænere på produktlisterne på den måde + jeg sætter automatisk canonical tag på så den beregner hvilket produktid der er primær, og på den måde undgår duplicate content.
det er jo rart at den selv finder ud af det, så det skal helst være en funktion som kan det samme hvis det skal laves om.

Men jeg må da tilstå at siden er blevet lidt langsommere efter jeg indførte det.

Men jeg er såmænd meget åben for ændringer, men ser bare lidt skeptisk på at lave noget onsave. Så hellere lave en funktion der er hurtigere.
Avatar billede erikjacobsen Ekspert
03. maj 2011 - 16:04 #16
Du kan samle nogle af de regulære udtryk, så der ikke er så mange, men ellers kan jeg ikke se en beregning, der kan være hurtigere.

En samling kan fx være at ændre:

  $title_product_name_remove_patterns[] = '/(\d+) kg./i';
  $title_product_name_remove_patterns[] = '/(\d+) kg/i';
  $title_product_name_remove_patterns[] = '/(\d+)kg./i';
  $title_product_name_remove_patterns[] = '/(\d+)kg/i';
  $title_product_name_remove_patterns[] = '/(\d+) ml./i';
  $title_product_name_remove_patterns[] = '/(\d+) ml/i';
  $title_product_name_remove_patterns[] = '/(\d+)ml./i';
  $title_product_name_remove_patterns[] = '/(\d+)ml/i';

til (vistnok)

  $title_product_name_remove_patterns[] = '/(\d+) ?(ml|kg)\.?/i';

Men ellers kan jeg ikke se noget problem i et forudberegnet felt i databasen.
Avatar billede learner Praktikant
03. maj 2011 - 17:40 #17
ja det var smart - jeg er ikke så god til det

angående: "Men ellers kan jeg ikke se noget problem i et forudberegnet felt i databasen."

jo hvis nu jeg pludselig ændrer $title_product_name_remove_patterns så er det som står i felterne jo ikke nutidigt men forældet og forkert. medmindre jeg laver noget smart der tager hånd om det.
Avatar billede learner Praktikant
03. maj 2011 - 18:31 #18
okay nu har jeg lavet dette:
$title_product_name_remove_patterns[] = '/(\d+) x /i';
$title_product_name_remove_patterns[] = '/ (\d+),(\d+) (cm|kg)\.?/i';
$title_product_name_remove_patterns[] = '/ (\d+)x(\d+) cm\.?/i';
$title_product_name_remove_patterns[] = '/ (\d+)-(\d+) (kilo|kg)\.?/i';
$title_product_name_remove_patterns[] = '/ (over|med) (\d+) (kilo|kg|pipetter)\.?/i';
$title_product_name_remove_patterns[] = '/ smagsprøve/i';
$title_product_name_remove_patterns[] = '/ ?(\d+) ?(ml|kg|stk|cm|gr|g)\.?/i';
$title_product_name_remove_patterns[] = '/ (XXXL|XXL|XL|XS|S|M|L)$/';
$title_product_name_remove_patterns[] = '/  /i';


Det ser ud til at alt virker som det skal og det fylder da i hvert fald mindre. Måske kan det forenkles lidt mere??
Avatar billede erikjacobsen Ekspert
03. maj 2011 - 19:06 #19
Hvis du "pludselig ændrer $title_product_name_remove_patterns", så kører du en opdatering af samtlige felter i databasen. Det er ligeyldigt om det tager 10 ms eller 10 sekunder.

Hvis du synes, kan du nu lave det hele som eet udtryk:

  $title_product_name_remove_patterns[]="(første udtryk)|(andet udtryk)";  // osv....

Men det bliver ikke mere læseligt af det.

Jeg formoder du skal bruge resultatet på serveren til generering af noget HTML, for ellers kunne man lægge beregningen ud i browseren i Javascript, hvor "der er tid nok".
Avatar billede learner Praktikant
03. maj 2011 - 19:34 #20
hej igen erikj

ja nu er det forsimplet så meget jeg kan, og jeg er tilfreds med det. kan godt se at der er mulighed for at forbedre det yderligere, men iflg speed test så kører hjemmesiden ok hurtigt.

du hjalp med mit spørgsmål, skønt, så smid gerne et svar

og tak for hjælpen :o)
Avatar billede erikjacobsen Ekspert
03. maj 2011 - 20:01 #21
Desværre, men jeg samler slet ikke på point, tak.
Avatar billede learner Praktikant
03. maj 2011 - 22:57 #22
OK tak :o)
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
Vi tilbyder markedets bedste kurser inden for webudvikling

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