[PHP] strpos en spaties

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

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Met behulp van de functie strpos ben ik opzoek naar de beginpositie van een bepaalde substring binnen een string. Met een andere functie, substr_replace, kan ik vervolgens die substring verwijderen.

Het probleem ontstaat wanneer ik met strpos opzoek ga naar een string, die een spatie bevat. Dit is een stukje voorbeeldcode:
PHP:
1
2
3
$tekst = "I am from Holland, from Holland I am";
$pos[1] = strpos($tekst, 'from'); // retourneert 5
$pos[2] = strpos($tekst, ', from'); // retourneert 0!

Zoals je ziet, zal $pos[2] het getal 0 retourneren (feitelijk boolean FALSE), omdat hij de opgegeven string (needle ;)) zogenaamd niet kan vinden. Ik had echter het getal 17 verwacht, omdat daar ", from Hol..." staat.

Het lijkt erop alsof er problemen ontstaan als mijn needle een spatie bevat. Klopt dat? En hoe werk ik dan om dit probleem heen? :)

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Ehm, misschien moet je je PHP versie eens updaten, of beter uit je ogen kijken... :)

Als ik dit doe:
PHP:
1
2
3
4
5
6
7
<?
$tekst = "I am from Holland, from Holland I am";
$pos[1] = strpos($tekst, 'from'); // retourneert 5
$pos[2] = strpos($tekst, ', from'); // retourneert 0!

print_r($pos);
?>


Dan krijg ik netjes:
code:
1
2
3
4
5
Array
(
    [1] => 5
    [2] => 17
)


Lijkt me dus een versieprobleem. :P

offtopic:
Bovendien is 0 in het geval van deze functie dus niet noodzakelijkerwijs gelijk aan false, dus check dat soort info altijd met de identiteitsoperator (===).

[ Voor 23% gewijzigd door NMe op 15-07-2004 21:20 ]

'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

Verwijderd schreef op 15 juli 2004 @ 20:45:
Met behulp van de functie strpos ben ik opzoek naar de beginpositie van een bepaalde substring binnen een string. Met een andere functie, substr_replace, kan ik vervolgens die substring verwijderen.

Het probleem ontstaat wanneer ik met strpos opzoek ga naar een string, die een spatie bevat. Dit is een stukje voorbeeldcode:
PHP:
1
2
3
$tekst = "I am from Holland, from Holland I am";
$pos[1] = strpos($tekst, 'from'); // retourneert 5
$pos[2] = strpos($tekst, ', from'); // retourneert 0!

Zoals je ziet, zal $pos[2] het getal 0 retourneren (feitelijk boolean FALSE), omdat hij de opgegeven string (needle ;)) zogenaamd niet kan vinden. Ik had echter het getal 17 verwacht, omdat daar ", from Hol..." staat.

Het lijkt erop alsof er problemen ontstaan als mijn needle een spatie bevat. Klopt dat? En hoe werk ik dan om dit probleem heen? :)
goed opletten, je hebt een typo gemaakt:
$pos[1] = strpos($tekst, 'from'); // retourneert 5
$pos[2] = strpos($tekst, ', from'); // retourneert 0!

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Verwijderd schreef op 15 juli 2004 @ 22:28:
[...]


goed opletten, je hebt een typo gemaakt:
$pos[1] = strpos($tekst, 'from'); // retourneert 5
$pos[2] = strpos($tekst, ', from'); // retourneert 0!
Dan mag je mij vertellen waar die typo staat? :?

Bovendien werkt de code die rachid.nl plaatste bij mij zonder enige aanpassing...

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

  • Hans1990
  • Registratie: Maart 2004
  • Niet online
Denk dat het een versie prob is want ik krijg ook gewoon 17 met phpversie 4.3.5 Download anders gewoon 5.0.0 :P (of je hebt die juist, nou gefeliciteerd. Je hebt een bug gevonden :P)

[ Voor 25% gewijzigd door Hans1990 op 15-07-2004 22:37 ]


Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Hans1990 schreef op 15 juli 2004 @ 22:36:
Denk dat het een versie prob is want ik krijg ook gewoon 17 met phpversie 4.3.5 Download anders gewoon 5.0.0 :P (of je hebt die juist, nou gefeliciteerd. Je hebt een bug gevonden :P)
Ik zou sowieso nog geen 5.0 gebruiken, puur om PHP5-afhankelijke code niet werkt op de meeste servers. En ik vermoed dat er gewoon een hele oude versie van PHP op zijn testserver staat. Lijkt me niet dat er ineens een fout sluipt in zo'n basale functie bij een simpele versie-upgrade. :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!

Verwijderd

Topicstarter
Dit is echt een vreemd probleem. Als ik de code vereenvoudig naar een voorbeeld zoals in de openingspost, bestaat het probleem niet. Ik weet niet hoe ik dit nu verder moet reproduceren. Ik kan wel de volledig PHP-code hier neerzetten, maar of dat nou zo wenselijk is..... :?

Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Doe anders maar wel even, kunnen wij even meekijken. ;)

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Oki, tussenweg:

De code vind je hier:

Uitvoerbaar: http://www.rachid.nl/test/gethoteldata.php
Leesbaar: http://www.rachid.nl/test/gethoteldata.txt

Het idee is dat er dmv XML-RPC een XML-pagina wordt gegenereerd. Met XSL worden daar MySQL statements van gemaakt, maar om een klein compatibiliteitsprobleempje te fixen, moet er nog e.e.a. aan data verwijderd worden. Die data heeft echter niet steeds een vaste positie en/of vaste lengte, waardoor er dus dmv string searches gezocht moet worden naar de juiste posities.

Op een gegeven moment wordt er gezocht naar ', from' (onder first occurence), maar doordat-ie dat zogenaamd niet kan vinden, wordt er een 0 geretourneerd, waardoor een groot gedeelte van mijn SQL-statement verdwijnt. De rest van het script zorgt er namelijk voor dat er van 0 tot x verwijderd wordt.

Ik kan in dit specieke voorbeeld niet naar 'from' zoeken, omdat die string bijvoorbeeld al verwerkt zit in de URL. Vandaar ', from', omdat dat veel unieker is. Blijkbaar zo uniek, dat-ie het niet kan vinden... ;)

Als je het script uitvoert, zie je bovenin de oorspronkelijke SQL-statement zoals gemaakt met behulp van XSL, en daaronder de bewerkte versie door bijvoorbeeld str-replace. Die versie is naturlijk hartstikke niet-werkend, omdat het hele begin van het statement verdwenen is.

Daar weer onder zie je een MySQL-error.

Thanks in advance! :Y)

Acties:
  • 0 Henk 'm!

  • stekkel
  • Registratie: Augustus 2001
  • Laatst online: 17-09 08:05
check eens op non breaking spaces.

Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
tip, copy/paste je .php naar .phps, krijg je syntax highligting. ;)

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Is de spatie in ', from' wel echt een spatie en geen ander vreemd teken?

'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

Topicstarter
NMe84 schreef op 16 juli 2004 @ 03:31:
Is de spatie in ', from' wel echt een spatie en geen ander vreemd teken?
Ja, dat kan bijna niet anders. Ik heb bovendien dat 'teken' maar eens gekopieerd en geplakt in de php-code, maar dat hielp niet.

Is er misschien niet een speciale code om dit soort spaties te representeren in PHP, zoals je \n en \r en zo hebt?

Acties:
  • 0 Henk 'm!

Verwijderd

Probeer anders eens:

code:
1
  $pos[2] = strpos($tekst, ','.chr(32).'from');

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Verwijderd schreef op 16 juli 2004 @ 11:36:
[...]


Ja, dat kan bijna niet anders. Ik heb bovendien dat 'teken' maar eens gekopieerd en geplakt in de php-code, maar dat hielp niet.

Is er misschien niet een speciale code om dit soort spaties te representeren in PHP, zoals je \n en \r en zo hebt?
Met regular expressions zou je kunnen matchen op \s, dan heb je alle whitespace karakters behalve enters. Kijk maar eens naar preg_replace().

'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

Topicstarter
Verwijderd schreef op 16 juli 2004 @ 11:43:
Probeer anders eens:

code:
1
  $pos[2] = strpos($tekst, ','.chr(32).'from');
Helaas wiseman, die hielp niet. :( Maar wel aardig gevonden! :)
Is er dan geen manier om uit te zoeken wat voor ascii-code precies hoort bij die 'spatie', zodat ik die permament in de code kan opnemen met chr(x)?

Acties:
  • 0 Henk 'm!

Verwijderd

beetje omslachtig maar wat mischien wel zou werken is:

code:
1
2
3
4
5
  $tekst = urlencode($tekst);

  $pos[2] = strpos($tekst, ',%20from');

  $tekst = urldecode($tekst);

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
@wiseman:

Het werkt, maar het werkt ook niet. Er komt wel een verrassing naar boven: de spatie is niet %20, maar %0A ! Geen idee wat dat is, maar misschien kan ik die in een string vangen en vervolgens decoderen. Ga ik zo eens proberen.

Waarom het verder niet goed werkt, is dat de posities niet meer kloppen. Het getal dat geretourneerd wordt, moet namelijk gebruikt worden om een offset te bepalen, maar doordat de string sterk van lengte verandert door urlencode, ontstaat er een probleem. :)

Maar bedankt, ik zit op een goed spoor nu!

Acties:
  • 0 Henk 'm!

Verwijderd

%0A = chr(10) = een LineFeed

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb nu verschillende varianten geprobeerd, maar het blijft maar niet werken! ;(

Variant 1:
PHP:
1
2
3
$spatie = urldecode("%0A");
$stringetje = ',' .$spatie .'from';
$posEerste = strpos($gezeik[$i], $stringetje);


Variant 2:
PHP:
1
2
$stringetje = ',' .chr(10) .'from';
$posEerste = strpos($gezeik[$i], $stringetje);


Ook in deze gevallen is $posEerste 0. :(

[ Voor 13% gewijzigd door Verwijderd op 16-07-2004 14:03 ]


Acties:
  • 0 Henk 'm!

Verwijderd

probeer dit eens, aangezien %0A een line feed is:

PHP:
1
2
3
4
5
<?
  $spatie = urldecode("%0A"); 
  $stringetje = ',\nfrom'; // zou ook \r kunnen zijn  :? 
  $posEerste = strpos($gezeik[$i], $stringetje);
?>

[ Voor 41% gewijzigd door Verwijderd op 16-07-2004 14:12 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
@wiseman:

Werkt ook niet! Maar wat me opvalt is dat als ik zo doe:
PHP:
1
2
$stringetje = ',\nfrom';
echo $stringetje; //retourneert ,\nfrom


Dat klopt toch niet? Er zou dan toch:

,
from

moeten staan? :?

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Verwijderd schreef op 16 juli 2004 @ 14:18:
@wiseman:

Werkt ook niet! Maar wat me opvalt is dat als ik zo doe:
PHP:
1
2
$stringetje = ',\nfrom';
echo $stringetje; //retourneert ,\nfrom


Dat klopt toch niet? Er zou dan toch:

,
from

moeten staan? :?
Staat er toch ook? Zie de source van je page.... :X
code:
1
2
3
"-2140479", "", 
from
"12:00"

Bovendien is het in Windows dan \r\n, dus replace dat maar eens...

[ Voor 33% gewijzigd door NMe op 16-07-2004 14:31 ]

'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

Topicstarter
@NMe84:
Het ging mij even om het stukje php-code wat daar stond. Ik dacht dat als je een string had waar \n in stond en je dat echo'de er ook echt een linebreak op het scherm kwam. Maar blijkbaar haal ik iets door elkaar. :)

Acties:
  • 0 Henk 'm!

  • Tsunami
  • Registratie: Juni 2002
  • Niet online
Verwijderd schreef op 16 juli 2004 @ 14:18:
@wiseman:

Werkt ook niet! Maar wat me opvalt is dat als ik zo doe:
PHP:
1
2
$stringetje = ',\nfrom';
echo $stringetje; //retourneert ,\nfrom


Dat klopt toch niet? Er zou dan toch:

,
from

moeten staan? :?
Als je single quotes gebruikt dan pakt ie die \n toch niet (net zomin als bijv. variabelen)? Ik moet iig altijd dubbele quotes gebruiken.

edit: dit werkt bij mij gewoon :?
PHP:
1
2
3
4
$tekst = "I am from Holland, from Holland I am"; 
$pos[1] = strpos($tekst, 'from'); // retourneert 5 
$pos[2] = strpos($tekst, ', from'); // retourneert 0!
echo "$pos[2]";

echoed ie gewoon 17...

[ Voor 28% gewijzigd door Tsunami op 16-07-2004 14:36 ]


Acties:
  • 0 Henk 'm!

Verwijderd

dj_tsunami schreef op 16 juli 2004 @ 14:33:
[...]

Als je single quotes gebruikt dan pakt ie die \n toch niet (net zomin als bijv. variabelen)? Ik moet iig altijd dubbele quotes gebruiken.
Yup, dat dacht ik ook, dubbele quotes kan het wel bij enkele niet

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

dj_tsunami schreef op 16 juli 2004 @ 14:33:
[...]

Als je single quotes gebruikt dan pakt ie die \n toch niet (net zomin als bijv. variabelen)? Ik moet iig altijd dubbele quotes gebruiken.
Klopt. :)

En @rachid.nl: Als je een \n afdrukt in een string krijg je geen enter in je browser, alleen in de source...

'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

Topicstarter
@NMe84:
En @rachid.nl: Als je een \n afdrukt in een string krijg je geen enter in je browser, alleen in de source...
|:( Damn... ha, nu voel ik me echt dom! Maar inderdaad, je hebt gelijk. :)

@DJTsunami:
Je hebt de post waarschijnlijk niet helemaal doorgelezen, maar het komt erop neer dat de voorbeeldcode die ik had gemaakt, niet overeenkomt met de werkelijke situatie. Daarom werkt het in de voorbeeldcode wel, maar in het echt niet. Lees maar ff door. ;)


Ik ga ff met str_replace op voorhand /r/n laten verwijderen, kijken wat er daarna gebeurt. :)

[ Voor 12% gewijzigd door Verwijderd op 16-07-2004 14:46 . Reden: Typo in functie ;) ]


Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Verwijderd schreef op 16 juli 2004 @ 14:43:
@NMe84:

[...]


|:( Damn... ha, nu voel ik me echt dom! Maar inderdaad, je hebt gelijk. :)

@DJTsunami:
Je hebt de post waarschijnlijk niet helemaal doorgelezen, maar het komt erop neer dat de voorbeeldcode die ik had gemaakt, niet overeenkomt met de werkelijke situatie. Daarom werkt het in de voorbeeldcode wel, maar in het echt niet. Lees maar ff door. ;)
Ik denk dat je het beste je string even kan bewerken door dit te doen:
PHP:
1
2
3
$str = str_replace("\r\n", " ", $str);
while (strpos($str, "  ") !== false)
  $str = str_replace("  ", " ", $str);

Zo hou je een string over zonder enters en met niet meer dan 1 spatie achter elkaar.

'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

NMe84 schreef op 16 juli 2004 @ 14:47:
[...]

Ik denk dat je het beste je string even kan bewerken door dit te doen:
PHP:
1
2
3
$str = str_replace("\r\n", " ", $str);
while (strpos($str, "  ") !== false)
  $str = str_replace("  ", " ", $str);

Zo hou je een string over zonder enters en met niet meer dan 1 spatie achter elkaar.
\r\n zouden 2 tekens zijn namelijk ASSCI-code 13 en 10 (0D0A) en aangezien er alleen 0A staat lijkt mij het sterk dat \r\n zal werken

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Verwijderd schreef op 16 juli 2004 @ 14:50:
[...]


\r\n zouden 2 tekens zijn namelijk ASSCI-code 13 en 10 (0D0A) en aangezien er alleen 0A staat lijkt mij het sterk dat \r\n zal werken
:P

PHP:
1
2
3
$str = str_replace(list("\r\n", "\r", "\n"), list(" ", " ", " "), $str);
while (strpos($str, "  ") !== false)
  $str = str_replace("  ", " ", $str);

Happy? :P

offtopic:
Wat is ASSCI? Is dat nieuw? :+

[ Voor 18% gewijzigd door NMe op 16-07-2004 14:58 ]

'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

Topicstarter
Yes guys, it works! :*)

Wiseman had wel een punt m.b.t. \r\n, dus ik heb \r en \n onafhankelijk van elkaar laten replacen door niets, zodat dat in ieder geval geen probleem was.

Kort samengevat was het probleem dus niet dat str_replace niet met spaties werkt, maar dat er überhaupt geen spatie stond! Dat zag ik over het hoofd, omdat ik de code in m'n browser bekeek... :z

Nu heb ik dus alle line-feeds en -breaks laten verwijderen, waardoor de code nu naar behoren werkt.

Iedereen bedankt! :D
Pagina: 1