[PHP] String filteren, alleen a-z en 1-9 toestaan

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

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Wanneer een bestand geupload wordt wil ik deze naam gebruiken in de url dat naar het bestand toe linked. Om deze rede zou ik er graag speciale tekens als ë, á, ", \, etc, etc uitfilteren (en wanneer mogelijk vervangen. Bijvoorbeeld 'ë' zou vervangen kunnen worden door 'e' en '\' door niets.

Ik heb hiervoor een functie geschreven waarvan de (waardeloze ;( ) kern er als volgt uit ziet:

code:
1
2
$uitz = array(alle denkbare tekens die niet toegestaan zijn, van ! tot +, van ë tot ®);
$zin = trim(stripslashes(strtolower(str_replace($uitz,"",$_REQUEST['bestandsnaam']))));


In een notendop som ik alles op wat niet mag en haal dit er uit. Een betere methode lijkt het mij om met reguliere expressies juist aan te geven wat wél mag en de rest er uit te filteren. Gezien louter a-z, 1-9 en eventueel - voor de spaties is toegestaan lijkt mij dat makkelijker, beter en efficienter.

Het tweede probleem is dat ik bepaalde tekens zoals boven beschreven wil vervangen, dit lukt, maar dit zou tevens een gigantische lijst worden. Het lijkt me dat ook dit korter kan..

Ik heb me suf gezocht op Google, PHP.net en een aantal forums, maar kan niet vinden wat ik nodig heb. Eventueel zou ik met reguliere expressies bovenstaande kunnen verkorten, maar ik wil het juist omdraaien en tevens tekens vervangen.

[ Voor 35% gewijzigd door Verwijderd op 26-11-2006 04:08 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Regular Expressions gebruiken en dan met name voor jou: preg_replace

Acties:
  • 0 Henk 'm!

  • MisterData
  • Registratie: September 2001
  • Laatst online: 29-08 20:29
preg_replace met een patroon als
code:
1
/[^A-Za-z0-9]/


laten replacen door "" :)

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

Verwijderd schreef op zondag 26 november 2006 @ 03:53:
Het tweede probleem is dat ik bepaalde tekens zoals boven beschreven wil vervangen, dit lukt, maar dit zou tevens een gigantische lijst worden. Het lijkt me dat ook dit korter kan..
Dat valt wel mee, het zijn er maar een stuk of 60 ;) (wij doen het ook gewoon met een array en strtr())
De rest kan je vervolgens strippen met een reguliere expressie ala
PHP:
1
$string = preg_replace('/[^\w .!~*():@=+$-]/', '', $string);

[ Voor 4% gewijzigd door crisp op 26-11-2006 12:32 ]

Intentionally left blank


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Bedankt allemaal! Ik kan het nu niet uitproberen want ben niet thuis, maar ga dit vanavond of morgen doen :)

Alleen vervangt preg_replace /[^A-Za-z0-9]/ niet juist alle tekens die ik wél wil toestaan? Of zou ik dan iets als preg_replace !/[^A-Za-z0-9]/ moeten gebruiken?

De teksten zijn louter NL en EN, dus Zweedse en Japanse tekens e.d. kan ik gewoon achterwege laten. Zal de code hier dan plaatsen zodat de zoekers er ook nog iets aan hebben.

[ Voor 22% gewijzigd door Verwijderd op 26-11-2006 14:59 ]


Acties:
  • 0 Henk 'm!

  • EdwinG
  • Registratie: Oktober 2002
  • Laatst online: 20:52
Verwijderd schreef op zondag 26 november 2006 @ 14:57:Alleen vervangt preg_replace /[^A-Za-z0-9]/ niet juist alle tekens die ik wél wil toestaan? Of zou ik dan iets als preg_replace !/[^A-Za-z0-9]/ moeten gebruiken?
Het gedeelte tussen [ en ] is een character-class, en de ^ aan het begin betekent 'alles dat niet is aangegeven'.
Pattern Syntax

Bezoek eens een willekeurige pagina


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Super! Het werkt gewoon, bedankt! :)

Voor de zoekers hieronder de code, altijd handig.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
// Eerst naar lowercase zodat bijvoorbeeld é en É niet beide gedefinieerd hoeven te worden.
$naam = strtolower($_POST['naam']);

// Array van de tekens die vervangen moeten worden.
$tekens = array("ß","à","á","â","ã","ä","å","ç","è","é","ê","ë","ì","í","î","ï","ñ","ò","ó","ô","õ","ö","ø","ù","ú","û","ü","ý","ÿ","š");

// Array van de vervangers.
$tekensvervang = array("S","a","a","a","a","a","a","c","e","e","e","e","i","e","e","e","n","o","o","o","o","o","o","u","u","u","u","y","y","s");

// De tekens vervangen.
$naam = str_replace($tekens,$tekensvervang,$naam);

// Alles wat niet a t/m z en 0-9 is verwijderen.
$naam = preg_replace('/[^a-z0-9]/', '', $naam);
?>

Acties:
  • 0 Henk 'm!

  • EnsconcE
  • Registratie: Oktober 2001
  • Laatst online: 19-06 00:07
Verwijderd schreef op maandag 27 november 2006 @ 00:36:
Super! Het werkt gewoon, bedankt! :)

Voor de zoekers hieronder de code, altijd handig.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
// Eerst naar lowercase zodat bijvoorbeeld é en É niet beide gedefinieerd hoeven te worden.
$naam = strtolower($_POST['naam']);

// Array van de tekens die vervangen moeten worden.
$tekens = array("ß","à","á","â","ã","ä","å","ç","è","é","ê","ë","ì","í","î","ï","ñ","ò","ó","ô","õ","ö","ø","ù","ú","û","ü","ý","ÿ","š");

// Array van de vervangers.
$tekensvervang = array("S","a","a","a","a","a","a","c","e","e","e","e","i","e","e","e","n","o","o","o","o","o","o","u","u","u","u","y","y","s");

// De tekens vervangen.
$naam = str_replace($tekens,$tekensvervang,$naam);

// Alles wat niet a t/m z en 0-9 is verwijderen.
$naam = preg_replace('/[^a-z0-9]/', '', $naam);
?>
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
// Array van de tekens die vervangen moeten worden.
$tekens = array("ß","à","á","â","ã","ä","å","ç","è","é","ê","ë","ì","í","î","ï","ñ","ò","ó","ô","õ","ö","ø","ù","ú","û","ü","ý","ÿ","š");

// Array van de vervangers.
$tekensvervang = array("S","a","a","a","a","a","a","c","e","e","e","e","i","e","e","e","n","o","o","o","o","o","o","u","u","u","u","y","y","s");

// De tekens vervangen. Ook hoofdletters
for ($i=0; $i < 2; $i++) {
    $naam = str_replace($tekens,$tekensvervang,$naam);
    $tekens = strtoupper($tekens);
    $tekensvervang = strtoupper($tekensvervang);
}

// Alles wat niet a t/m z en 0-9 is verwijderen.
$naam = preg_replace('/[^a-z0-9]/', '', $naam);
?>

Om de invoer goed te houden ;)

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

offtopic:
Een ß staat niet voor een hoofdletter S, maar voor een dubbele s. Het is dus eigenlijk Strasse op zijn Duits, niet StraSe, wanneer iemand Straße invult. :)

'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!

  • Zyppora
  • Registratie: December 2005
  • Laatst online: 12-09 10:59

Zyppora

155/50 Warlock

Waarom een loop?

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php 
// Array van de tekens die vervangen moeten worden. 
$tekens = array("ß","à","á","â","ã","ä","å","ç","è","é","ê","ë","ì","í","î","ï","ñ","ò","ó","ô","õ","ö","ø","ù","ú","û","ü","ý","ÿ","š"); 

// Array van de vervangers. 
$tekensvervang = array("S","a","a","a","a","a","a","c","e","e","e","e","i","e","e","e","n","o","o","o","o","o","o","u","u","u","u","y","y","s"); 

// De tekens vervangen. Ook hoofdletters 
$naam = str_replace($tekens,$tekensvervang,$naam); 
$tekens = strtoupper($tekens); 
$tekensvervang = strtoupper($tekensvervang); 
$naam = str_replace($tekens,$tekensvervang,$naam); 

// Alles wat niet a t/m z en 0-9 is verwijderen. 
$naam = preg_replace('/[^a-z0-9]/', '', $naam); 
?>

Phenom II X4 945 \\ 8GB DDR3 \\ Crosshair IV Formula \\ R9 290


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

-NMe- schreef op maandag 27 november 2006 @ 13:48:
offtopic:
Een ß staat niet voor een hoofdletter S, maar voor een dubbele s. Het is dus eigenlijk Strasse op zijn Duits, niet StraSe, wanneer iemand Straße invult. :)
Net als æ die je kan vervangen door 'ae'

Overigens zou ik de hoofdletters ook alvast meenemen in de arrays, dat performed zeker beter dan 2x een replace uitvoeren plus een strtoupper over beide arrays. Kijk overigens ook eens naar strtr() - daar kan je een associatieve array gebruiken.

[ Voor 27% gewijzigd door crisp op 27-11-2006 13:56 ]

Intentionally left blank


Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Waarom een loop? Omdat strtoupper volgens de manual een string verwacht en geen array van strings. Je zou wel iets als array_walk kunnen gebruiken om een handmatige loop te vermijden, maar intern gebeurt het dan nog steeds wel. :P

'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!

  • Zyppora
  • Registratie: December 2005
  • Laatst online: 12-09 10:59

Zyppora

155/50 Warlock

-NMe- schreef op maandag 27 november 2006 @ 13:54:
Waarom een loop? Omdat strtoupper volgens de manual een string verwacht en geen array van strings. Je zou wel iets als array_walk kunnen gebruiken om een handmatige loop te vermijden, maar intern gebeurt het dan nog steeds wel. :P
Goed, ik wilde slechts aangeven dat een loop in de gegeven code een beetje overbodig was, ook met het oog op de twee strtoupper() aanroepen die de tweede keer voor nop draaien. De syntax van strtoupper() ken ik niet van buiten, en dus ook de parameters niet (ik ga er dan ook vanuit dat dit uitzoekwerk voor de TS is :P )

Phenom II X4 945 \\ 8GB DDR3 \\ Crosshair IV Formula \\ R9 290


Acties:
  • 0 Henk 'm!

  • EnsconcE
  • Registratie: Oktober 2001
  • Laatst online: 19-06 00:07
@-NMe-
Dan klopt die van mij nog steeds niet :X

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Klopt, maar dan nog is er wel een loop nodig. :P Om helemaal eerlijk te zijn had ik je code niet eens echt doorgelezen. :+

'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!

  • BtM909
  • Registratie: Juni 2000
  • Niet online

BtM909

Watch out Guys...

crisp schreef op maandag 27 november 2006 @ 13:53:
[...]

Net als æ die je kan vervangen door 'ae'
offtopic:
Om nog ff lekker verder te gaan:
ä = ae
ü =ue
ö = oe

;)

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

Topicstarter
Bedankt voor de tips. Zal deze toevoegen. Zoals je ziet was Duits niet mijn beste vak op school.. ;)

Die loop is voor mij overigens niet nodig omdat ik alles lowercase wil, echter voor andere delen is dit wel verrekte handig! :)

[ Voor 39% gewijzigd door Verwijderd op 27-11-2006 16:54 ]


Acties:
  • 0 Henk 'm!

  • BrainSmasher
  • Registratie: November 2006
  • Laatst online: 20:32
ß = ss
Om het compleet te maken.

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

Om het helemaal compleet te maken:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
function filter($string)
{
    return preg_replace(
                '/[^A-Za-z0-9]/',
                '',
                strtr(
                    $string,
                    array(
                        'Ä' =>  'Ae',
                        'Æ' =>  'Ae',
                        'Ö' =>  'Oe',
                        'Ü' =>  'Ue',
                        'ß' =>  'ss',
                        'ä' =>  'ae',
                        'æ' =>  'ae',
                        'ö' =>  'oe',
                        'ü' =>  'ue',
                        'À' =>  'A',
                        'Á' =>  'A',
                        'Â' =>  'A',
                        'Ã' =>  'A',
                        'Å' =>  'A',
                        'Ç' =>  'C',
                        'È' =>  'E',
                        'É' =>  'E',
                        'Ê' =>  'E',
                        'Ë' =>  'E',
                        'Ì' =>  'I',
                        'Í' =>  'I',
                        'Î' =>  'I',
                        'Ï' =>  'I',
                        'Ñ' =>  'N',
                        'Ò' =>  'O',
                        'Ó' =>  'O',
                        'Ô' =>  'O',
                        'Õ' =>  'O',
                        '×' =>  'x',
                        'Ø' =>  'O',
                        'Ù' =>  'U',
                        'Ú' =>  'U',
                        'Û' =>  'U',
                        'Ý' =>  'Y',
                        'à' =>  'a',
                        'á' =>  'a',
                        'â' =>  'a',
                        'ã' =>  'a',
                        'ç' =>  'c',
                        'è' =>  'e',
                        'é' =>  'e',
                        'ê' =>  'e',
                        'ë' =>  'e',
                        'ì' =>  'i',
                        'í' =>  'i',
                        'î' =>  'i',
                        'ï' =>  'i',
                        'ñ' =>  'n',
                        'ò' =>  'o',
                        'ó' =>  'o',
                        'ô' =>  'o',
                        'õ' =>  'o',
                        'ø' =>  'o',
                        'ù' =>  'u',
                        'ú' =>  'u',
                        'û' =>  'u',
                        'ý' =>  'y',
                        'ÿ' =>  'y'
                    )
                )
        );
}

;)

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44

MBV

offtopic:
Was dat wel OSS, Crisp? Niet stiekem uit React gejat? ;)

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

MBV schreef op maandag 27 november 2006 @ 22:13:
offtopic:
Was dat wel OSS, Crisp? Niet stiekem uit React gejat? ;)
offtopic:
Nee, dat komt niet uit React en zelfs niet helemaal uit de FP code hoewel we wel een soortgelijke (maar meer uitgebreide) constructie gebruiken voor de friendly url's ;)

Intentionally left blank


Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Overcompleet zelfs. :+
-NMe- schreef op maandag 27 november 2006 @ 13:48:
offtopic:
Een ß staat niet voor een hoofdletter S, maar voor een dubbele s. Het is dus eigenlijk Strasse op zijn Duits, niet StraSe, wanneer iemand Straße invult. :)
;)

'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!

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 05-09 14:39

_Thanatos_

Ja, en kaal

crisp schreef op zondag 26 november 2006 @ 12:31:
[...]

Dat valt wel mee, het zijn er maar een stuk of 60 ;) (wij doen het ook gewoon met een array en strtr())
De rest kan je vervolgens strippen met een reguliere expressie ala
PHP:
1
$string = preg_replace('/[^\w .!~*():@=+$-]/', '', $string);
Hij zijn er wel iets meer... unicode enzo ;)

日本!🎌


Acties:
  • 0 Henk 'm!

  • Sander
  • Registratie: Juni 2004
  • Niet online
crisp schreef op maandag 27 november 2006 @ 22:08:
Om het helemaal compleet te maken:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
function filter($string)
{
    return preg_replace(
                '/[^A-Za-z0-9]/',
                '',
                strtr(
                    $string,
                    array(
                        'Ä' =>  'Ae',
                        'Æ' =>  'Ae',
                        'Ö' =>  'Oe',
                        'Ü' =>  'Ue',
                        'ß' =>  'ss',
                        'ä' =>  'ae',
                        'æ' =>  'ae',
                        'ö' =>  'oe',
                        'ü' =>  'ue',
                        'À' =>  'A',
                        'Á' =>  'A',
                        'Â' =>  'A',
                        'Ã' =>  'A',
                        'Å' =>  'A',
                        'Ç' =>  'C',
                        'È' =>  'E',
                        'É' =>  'E',
                        'Ê' =>  'E',
                        'Ë' =>  'E',
                        'Ì' =>  'I',
                        'Í' =>  'I',
                        'Î' =>  'I',
                        'Ï' =>  'I',
                        'Ñ' =>  'N',
                        'Ò' =>  'O',
                        'Ó' =>  'O',
                        'Ô' =>  'O',
                        'Õ' =>  'O',
                        '×' =>  'x',
                        'Ø' =>  'O',
                        'Ù' =>  'U',
                        'Ú' =>  'U',
                        'Û' =>  'U',
                        'Ý' =>  'Y',
                        'à' =>  'a',
                        'á' =>  'a',
                        'â' =>  'a',
                        'ã' =>  'a',
                        'ç' =>  'c',
                        'è' =>  'e',
                        'é' =>  'e',
                        'ê' =>  'e',
                        'ë' =>  'e',
                        'ì' =>  'i',
                        'í' =>  'i',
                        'î' =>  'i',
                        'ï' =>  'i',
                        'ñ' =>  'n',
                        'ò' =>  'o',
                        'ó' =>  'o',
                        'ô' =>  'o',
                        'õ' =>  'o',
                        'ø' =>  'o',
                        'ù' =>  'u',
                        'ú' =>  'u',
                        'û' =>  'u',
                        'ý' =>  'y',
                        'ÿ' =>  'y'
                    )
                )
        );
}

;)
Sorry voor de kick van dit oude topic, maar ik probeer deze code te gebruiken, maar op de 1 of andere manier replaced hij de waarden niet door de corresponderende values, maar door anderen. Zo wordt de é vervangen door een A. Iemand een idee?

Doel is het vereenvoudigen van de strings die binnenkomen vanuit een XML feed, om ze zo beter te kunnen matchen tegen een naam uit een andere feed. Bijv Blof en bløf, of Acda en de munnik en Acda & de munnik.

En anders een idee hoe dit wel op te lossen? Of misschien een slimme builtin feature waar ik nu totaal overheen kijk?

Acties:
  • 0 Henk 'm!

  • Svennetjee
  • Registratie: December 2007
  • Laatst online: 18:13
Wat dachten jullie van de functie chr()?

Acties:
  • 0 Henk 'm!

  • tech-no-logical
  • Registratie: December 2000
  • Laatst online: 17-09 22:52
PHP:
1
$string = iconv("UTF-8","ASCII//TRANSLIT",$string);


je input charset kan natuurlijk ook iets anders zijn, zoals ISO8859-1.

Acties:
  • 0 Henk 'm!

  • doeternietoe
  • Registratie: November 2004
  • Laatst online: 21:26
Wat wilde je daar dan mee?

@poster hierboven:
Over je probleem kan ik niet zoveel zeggen, het klink in ieder geval heel vreemd. Misschien kan je een zo klein mogelijke lap code sturen waar het probleem bij optreedt...

Als ik begrijp ben je een soort zoekalgoritme aan het maken met behulp van php en xml. Om eerlijk te zijn geloof ik dat dit niet de meest gelukkige combinatie is. (ga je iedere keer enkele tientallen of nog meer xml-bestanden inlezen?) Zoekwoorden in MySQLzetten en van de functies van MySQL gebruik maken lijkt me vele malen beter presteren.

Acties:
  • 0 Henk 'm!

  • Sander
  • Registratie: Juni 2004
  • Niet online
doeternietoe schreef op woensdag 22 oktober 2008 @ 22:09:
[...]

Wat wilde je daar dan mee?

@poster hierboven:
Over je probleem kan ik niet zoveel zeggen, het klink in ieder geval heel vreemd. Misschien kan je een zo klein mogelijke lap code sturen waar het probleem bij optreedt...

Als ik begrijp ben je een soort zoekalgoritme aan het maken met behulp van php en xml. Om eerlijk te zijn geloof ik dat dit niet de meest gelukkige combinatie is. (ga je iedere keer enkele tientallen of nog meer xml-bestanden inlezen?) Zoekwoorden in MySQLzetten en van de functies van MySQL gebruik maken lijkt me vele malen beter presteren.
De bedoeling is om verschillende feeds met producten te matchen met bestaande database data. Omdat dit om een stuk of 5 feeds gaat, die allemaal eens per dag ingelezen worden (geautomatiseerd) is het de bedoeling dit zoveel mogelijk geautomatiseerd te doen. In de feeds worden automatisch een aantal eigenschappen meegegeven op basis waarvan ze in de relationele database komen te hangen. Voor het opzoeken van de juiste koppelingen in de MySQL database probeer ik dus de betreffende velden te vereenvoudigen om zo simpele "fouten" alvast af te kunnen vangen. Na het importeren kan de beheerder alsnog eventuele invoerfouten corrigeren. Zo wil de klant het hebben... :)

Ik wil deze functie dus gebruiken om deze versimpelingsslag uit te voeren. Naast het filteren van diakrieten wil ik bijv het & teken laten vervangen door 'en' etc. Dat zijn uiteraard simpele stappen, maar dan moet dit wel werken...

Na wat verder testen heb ik nu gemerkt dat als ik de functie in een aparte testfile plak en daar niks anders doe dan de string invoeren en laten replacen dan gaat het goed. Plak ik dezelfde functie in mijn class, dan matched hij verkeerd... Alle diakrieten worden vervangen door een hoofdletter A ipv hun versimpelde tegenhanger in de array.

Ik ben me nu echt aan het afvragen hoe dit kan, ik heb toch aardig wat ervaring met PHP, maar hier kan ik met mijn gedachten even niet bij...

Dingen die bij me opkomen zijn:
- Array pointer verspringt op de 1 of andere vage manier?
- Door de karakterset van de inputstring gaat er wat verkeerd?

Acties:
  • 0 Henk 'm!

Verwijderd

Als de input unicode is zou je ook gebruik kunnen maken van unicode decomposition (geen idee of php daar functies voor heeft).

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Het probleem is dat je data in UTF-8 geencodeerd is, maar je script niet. Een é in UTF-8 wordt bijvoorbeeld geencodeerd als de twee tekens 0xC3 0xA9. In je script, dat waarschijnlijk Windows 1252 of Latin-1 is, wordt een é geencodeerd als 0xE9. 0xC3 in Latin-1 staat voor de Ã, en 0xA9 voor de ©, wat verklaart dat een é in UTF-8 door jouw script wordt omgezet naar een A.

Om het nog leuker te maken, alle diakrieten in Latin-1 hebben een waarde boven de 0xC0, die bovendien overeenkomen met hun unicode codepoint, en hebben dus het bitpatroon [11xx yyyy]. Als je de unicode codepoints met dat bitpatroon gaat coderen in UTF-8 dan krijg je de twee bytes [1100 0011] [10xx yyyy], oftewel een 0xC3 gevolgd door een byte in de range 0x80 - 0xbf.

0xC3 staat dus voor Ã, en alle bytes in Latin-1/Win1252 in de range 0x80 - 0xbf zijn speciale tekens. Met andere woorden, ál je diakrieten, die twee bytes innemen in UTF-8, worden omgezet naar de hoofdletter A voor de eerste byte en weggefilterd voor de tweede byte, waardoor je een enkele A overhoudt.

Dit probleem kun je oplossen door ofwel je script ook te encoderen in UTF-8 (de meeste degelijke editors ondersteunen dit wel), ofwel door van tevoren de waarden in de array te converteren van Latin-1 naar UTF-8, ofwel je data te converteren van UTF-8 naar Latin-1 voordat je de omzetting doet. Het mooie van het filter is overigens dat de overgebleven karakters identiek zijn in UTF-8 en Latin-1, dus je hoeft ook niet terug te converteren als je voor die laatste optie kiest (welke imho de handigste is)

[ Voor 29% gewijzigd door .oisyn op 23-10-2008 01:08 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
-sander-: Je bent aan het falen met character encodings. ;)

{signature}


Acties:
  • 0 Henk 'm!

  • Sander
  • Registratie: Juni 2004
  • Niet online
Voutloos schreef op donderdag 23 oktober 2008 @ 09:15:
-sander-: Je bent aan het falen met character encodings. ;)
zeker weten, en niet een klein beetje ook. Helaas nog weinig ervaring met deze dingen.

De binnenkomende feed is ISO-8859-1, wanneer ik deze dmv mb_strings module converteer naar UTF-8 ben ik direct al mijn tekens kwijt, dit wil ik niet aangezien ik ze dan niet meer kan matchen.

Mijn code nu (file is UTF-8)
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<?php
        function filterInput($string) 
        { 
            return preg_replace( 
                        '/[^A-Za-z0-9]/', 
                        '', 
                        strtr( 
                            $string, 
                            array( 
                                'Ä' =>  'Ae', 
                                'Æ' =>  'Ae', 
                                'Ö' =>  'Oe', 
                                'Ü' =>  'Ue', 
                                'ß' =>  'ss', 
                                'ä' =>  'ae', 
                                'æ' =>  'ae', 
                                'ö' =>  'oe', 
                                'ü' =>  'ue', 
                                'À' =>  'A', 
                                'Á' =>  'A', 
                                'Â' =>  'A', 
                                'Ã' =>  'A', 
                                'Å' =>  'A', 
                                'Ç' =>  'C', 
                                'È' =>  'E', 
                                'É' =>  'E', 
                                'Ê' =>  'E', 
                                'Ë' =>  'E', 
                                'Ì' =>  'I', 
                                'Í' =>  'I', 
                                'Î' =>  'I', 
                                'Ï' =>  'I', 
                                'Ñ' =>  'N', 
                                'Ò' =>  'O', 
                                'Ó' =>  'O', 
                                'Ô' =>  'O', 
                                'Õ' =>  'O', 
                                '×' =>  'x', 
                                'Ø' =>  'O', 
                                'Ù' =>  'U', 
                                'Ú' =>  'U', 
                                'Û' =>  'U', 
                                'Ý' =>  'Y', 
                                'à' =>  'a', 
                                'á' =>  'a', 
                                'â' =>  'a', 
                                'ã' =>  'a', 
                                'ç' =>  'c', 
                                'è' =>  'e', 
                                'é' =>  'e', 
                                'ê' =>  'e', 
                                'ë' =>  'e', 
                                'ì' =>  'i', 
                                'í' =>  'i', 
                                'î' =>  'i', 
                                'ï' =>  'i', 
                                'ñ' =>  'n', 
                                'ò' =>  'o', 
                                'ó' =>  'o', 
                                'ô' =>  'o', 
                                'õ' =>  'o', 
                                'ø' =>  'o', 
                                'ù' =>  'u', 
                                'ú' =>  'u', 
                                'û' =>  'u', 
                                'ý' =>  'y', 
                                'ÿ' =>  'y' 
                            ) 
                        ) 
                ); 
        }


$xml = mb_convert_encoding($xml, 'ISO-8859-1', 'UTF-8');

// Maak de XML bereikbaar dmv XMLSimple van PHP5
$xml = new SimpleXMLElement($xml);

foreach ($xml->product as $product) {
    
echo $product->additional->venue . " - " . filterInput($product->additional->venue) . '<br />';
}
?>


Stukkie voorbeeld XML:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="iso-8859-1"?>
<productFeed>

    <product id="20202">
        <name><![CDATA[Omara Portuondo]]></name>
        <price>19.00</price>
        <additional>
            <date>25-10-2008</date>
            <venue><![CDATA[Carré]]></venue>
            <city><![CDATA[Amsterdam]]></city>
            <country><![CDATA[Nederland]]></country>
        </additional>
    </product>
</productFeed>

Acties:
  • 0 Henk 'm!

  • supakeen
  • Registratie: December 2000
  • Laatst online: 09-09 14:42
PHP:
1
2
3
4
5
<?php

  header("Content-Type: text/html; charset=utf-8");

?>

Bovenaan je bestand meppen anders weet de browser niet watskeburt.

[ Voor 7% gewijzigd door supakeen op 23-10-2008 14:48 ]


Acties:
  • 0 Henk 'm!

Verwijderd

* sorry voor de kick, maar vond net de (waarschijnlijke oorzaak) oorzaak van Sander's probleem, dus vond het het vermelden waard *

@Sander, het heeft vermoedelijk met de tekenset te maken:

voor de strtr in de filter functie ff:

PHP:
1
2
3
$string = utf8_decode($string);

return preg_replace('','','')
Pagina: 1