[php] spatie invoegen in string

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

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Haranaka
  • Registratie: September 2000
  • Laatst online: 08-09 09:36
Ik heb een waarde x die 36 chars bevat, maar voor verdere verwerking moet deze lange string onderbroken worden in 4 stukken van ieder 8 chars. Ik zoeken op php.net en kwam op de functie wordwrap, maar die doet niet wat ik wil :(

PHP:
1
2
3
$x="00001ad3b32fdd596d31283800000000";
$newx=wordwrap($x, 8," ");
echo "$newx\n";


Hieruit verwacht ik dat hij zegt:

00001ad3 b32fdd59 6d312838 00000000

Dat hij dus om de 8 chars een spatie invoegt. Maar je verwacht het al, het werkt niet zoals ik wil, anders zou ik het hier niet posten. Hij spuigt gewoon de oude waarde uit, dus zonder spaties.

Iemand die me uit de brand kan helpen?

...


Acties:
  • 0 Henk 'm!

  • Sybr_E-N
  • Registratie: December 2001
  • Laatst online: 17-09 22:12
Kun je niet iets maken met de functie str_split? Je zit dan wel met array's opgescheep, of met een normaal while of for lusje kun je jouw string ook wel in stukken splitsen.

Acties:
  • 0 Henk 'm!

  • Haranaka
  • Registratie: September 2000
  • Laatst online: 08-09 09:36
Mijn eerste gedacht was ook str_split, maar die is : (PHP 5 CVS only)

ik wil graag een while lus voorkomen omdat ik het in een script moet verwerken dat het zo'n 10.000 keer moet doen.

...


Acties:
  • 0 Henk 'm!

  • corani
  • Registratie: December 2000
  • Laatst online: 05-10-2017

corani

__,,,_(^_^)_,,,__

Is die string altijd 32 tekens?

PHP:
1
$x = substr($x, 0, 8)." ".substr($x, 8, 8)." ".substr($x, 16, 8)." ".substr($x, 24, 8);


zoiets?

Laat me nou toch eens met rust man!
Iedereen die in telekinese gelooft, steek a.u.b. mijn hand op


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

En dan hebben ze zo'n duidelijke manual :)
string wordwrap ( string str [, int width [, string break [, boolean cut]]])

Returns a string with str wrapped at the column number specified by the optional width parameter. The line is broken using the (optional) break parameter.

wordwrap() will automatically wrap at column 75 and break using '\n' (newline) if width or break are not given.

If the cut is set to 1, the string is always wrapped at the specified width. So if you have a word that is larger than the given width, it is broken apart. (See second example).

Acties:
  • 0 Henk 'm!

Verwijderd

Waarom gebruik je
PHP:
1
substr() ;

niet?

Acties:
  • 0 Henk 'm!

  • Sybr_E-N
  • Registratie: December 2001
  • Laatst online: 17-09 22:12
Ow, maar substr() werkt ook wel.

Krijg je het volgende:
PHP:
1
2
3
4
5
6
$x= '00001ad3b32fdd596d31283800000000';

$sub1 = substr($x, 0, 8);
$sub2 = substr($x, 8, 8);
$sub3 = substr($x, 16, 8);
$sub4 = substr($x, 24, 8);

Acties:
  • 0 Henk 'm!

  • Haranaka
  • Registratie: September 2000
  • Laatst online: 08-09 09:36
Doh |:( , thanks ACM. Ook de anderen btw

...


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
maak er wel even iets moois van mensen, dat op alle lengtes werkt...

PHP:
1
2
3
4
5
while ($i < strlen($string))
{
  $string2 = substr($string,$i,8) . " ";
  $i+=8;
}

[ Voor 10% gewijzigd door Grijze Vos op 06-11-2003 20:09 ]

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


Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 12:56
Grijze Vos schreef op 06 november 2003 @ 20:08:
maak er wel even iets moois van mensen, dat op alle lengtes werkt...

PHP:
1
2
3
4
5
while ($i < strlen($string))
{
  $string2 = substr($string,$i,8) . " ";
  $i+=8;
}
zie ook:
ik wil graag een while lus voorkomen omdat ik het in een script moet verwerken dat het zo'n 10.000 keer moet doen.
Als het een eenmalige oplossing is dan is het wel oke zoals de TS het nu doet. Maar als je een beetje een universeel systeempje wilt maken is de oplossing van grijze vos beter.

Acties:
  • 0 Henk 'm!

  • stekkel
  • Registratie: Augustus 2001
  • Laatst online: 17-09 08:05
De allersnelste oplossing:

PHP:
1
$splitted_string = chunk_split ( $string , 8 , ' ');

:)

[ Voor 49% gewijzigd door stekkel op 06-11-2003 20:35 ]


Acties:
  • 0 Henk 'm!

  • CrashOne
  • Registratie: Juli 2000
  • Niet online

CrashOne

oOoOoOoOoOoOoOoOoOo

Heb net een mooie (naar mijn idee) functie geschreven, wel asp:

VBScript:
1
2
3
4
5
6
7
8
9
10
11
12
Function cutWord(text)

    dim mess
    set mess = new regexp

    mess.pattern = "(\S{25}?)(\S{25}?)"

    text = mess.replace(text, "$1-<br>$2")

    cutWord = text

End Function


Kan natuurlijk altijd dynamischer door je lengte ook in de functie mee te geven.

[ Voor 11% gewijzigd door CrashOne op 06-11-2003 22:38 . Reden: edit de edit de edit ]

Huur mij in als freelance SEO consultant!


Acties:
  • 0 Henk 'm!

  • Burat
  • Registratie: Oktober 1999
  • Niet online

Burat

bos wortels

Een regexp is zwaar overkill. De substr is denk ik het snelst omdat die direct naar een c functie wordt gemapt. Vooral als het 10.000 keer uitgevoerd moet worden.

Voor performance checken is het misschien aardig om even te profilen wat het snelst gaat. Leuk tooltje hiervoor is apd (http://pecl.php.net/package/apd)

Homepage | Me @ T.net | Having fun @ Procurios | Collega's gezocht: Webontwikkelaar PHP


Acties:
  • 0 Henk 'm!

  • stekkel
  • Registratie: Augustus 2001
  • Laatst online: 17-09 08:05
Burat schreef op 07 november 2003 @ 08:09:
Een regexp is zwaar overkill. De substr is denk ik het snelst omdat die direct naar een c functie wordt gemapt. Vooral als het 10.000 keer uitgevoerd moet worden.
substr vereist in dit geval 4 substr functie aanroepen en het vereist dat er concatinatie plaats moet middels implode.

chunk_split is 1 functie aanroep en concatinatie is niet nodig.

Wat zal sneller zijn? :)

Acties:
  • 0 Henk 'm!

  • Burat
  • Registratie: Oktober 1999
  • Niet online

Burat

bos wortels

Het is niet vanzelfsprekend dat die ene aanroep sneller is: sommige functies worden 1 op 1 gemapt naar een c-functie, zonder dat de php/zend engine er iets mee hoeft te doen waardoor het sneller is dan een korte 'simpele' functie.

In dit geval heb je gelijk, jouw oplossing is sneller.

test1.php
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
<?php

apd_set_pprof_trace();
$string = "00001ad3b32fdd596d31283800000000";

for($i=0; $i < 10000; $i++)
{       $splitted_string = chunk_split ($string, 8, ' ');
}

echo $splitted_string;

?>


test2.php
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
<?php

apd_set_pprof_trace();
$string = "00001ad3b32fdd596d31283800000000";

for($i=0; $i < 10000; $i++)
{       $splitted_string = substr($string, 0, 8).' '.substr($string, 8, 8).' '.substr($string, 16, 8).' '.substr($string, 24, 8);
}

echo $splitted_string;

?>


En de snelheid:
code:
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
root@devbak1:/data/www/apd_dump# pprofp -u pprof.06866

Trace for /home/bslagter/test/test1.php
Total Elapsed Time =    0.24
Total System Time  =    0.00
Total User Time    =    0.24


         Real         User        System             secs/    cumm
%Time (excl/cumm)  (excl/cumm)  (excl/cumm) Calls    call    s/call  Memory Usage Name
--------------------------------------------------------------------------------------
100.0  0.24  0.24   0.24  0.24   0.00  0.00  10000   0.0000    0.0000            0 chunk_split
  0.0  0.00  0.00   0.00  0.00   0.00  0.00     1   0.0000    0.0000            0 main
root@devbak1:/data/www/apd_dump# pprofp -u pprof.06867

Trace for /home/bslagter/test/test2.php
Total Elapsed Time =    0.78
Total System Time  =    0.00
Total User Time    =    0.78


         Real         User        System             secs/    cumm
%Time (excl/cumm)  (excl/cumm)  (excl/cumm) Calls    call    s/call  Memory Usage Name
--------------------------------------------------------------------------------------
100.0  0.78  0.78   0.78  0.78   0.00  0.00  40000   0.0000    0.0000            0 substr
  0.0  0.00  0.00   0.00  0.00   0.00  0.00     1   0.0000    0.0000            0 main

Homepage | Me @ T.net | Having fun @ Procurios | Collega's gezocht: Webontwikkelaar PHP


Acties:
  • 0 Henk 'm!

  • Spider.007
  • Registratie: December 2000
  • Niet online

Spider.007

* Tetragrammaton

offtopic:
w00t die " APD extension"s zien er heel erg goed uit Burat :)

---
Prozium - The great nepenthe. Opiate of our masses. Glue of our great society. Salve and salvation, it has delivered us from pathos, from sorrow, the deepest chasms of melancholy and hate


Acties:
  • 0 Henk 'm!

  • stekkel
  • Registratie: Augustus 2001
  • Laatst online: 17-09 08:05
Burat schreef op 09 november 2003 @ 22:55:
Het is niet vanzelfsprekend dat die ene aanroep sneller is: sommige functies worden 1 op 1 gemapt naar een c-functie, zonder dat de php/zend engine er iets mee hoeft te doen waardoor het sneller is dan een korte 'simpele' functie.

In dit geval heb je gelijk, jouw oplossing is sneller.
Burat _/-\o_

Ben er mee eens dat het niet vanzelf sprekend is maar door voldoende ervaring weet ik inmiddels wel welke functies binnen php tijd kosten en welke snel zijn. (ik heb te veel php performance tuning docs gelezen)

Bedankt dat je het getest hebt !!!

Volgende keer zal ik het zelf testen, nadat ik dat apd geinstalleerd heb. Heb al veel van die apd uitdraaien gezien maar ben altijd te lui geweest om het op mijn eigen server te installeren :/

Acties:
  • 0 Henk 'm!

Verwijderd

Burat: Een regexp is zwaar overkill.
Hrmph.
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
function timer() {
    static $prev, $last = 0;
    $prev = $last;
    $last = array_sum(explode(" ", microtime()));
    return $last - $prev;
}

$string = "00001ad3b32fdd596d31283800000000";
$iters  = 500000;

echo "Doing $iters iterations...\n";
timer();
for ($i = 0; $i < $iters; $i++) {
    $splitted_string = substr($string, 0,  8) . ' '
                     . substr($string, 8,  8) . ' '
                     . substr($string, 16, 8) . ' '
                     . substr($string, 24, 8);
}
echo "4 times substr:     ", timer(), " seconds\n";
// echo "Result: $splitted_string\n";

timer();
for ($i = 0; $i < $iters; $i++) {
    $splitted_string = preg_replace('/(.{8})/', '$1 ', $string);
}
echo "preg_replace (NL):  ", timer(), " seconds\n";
// echo "Result: $splitted_string\n";

timer();
for ($i = 0; $i < $iters; $i++) {
    $splitted_string = preg_replace('/(.{8})/', '$1 ', $string, 3);
}
echo "preg_replace (L=3): ", timer(), " seconds\n";
// echo "Result: $splitted_string\n";

code:
1
2
3
4
Doing 500000 iterations...
4 times substr:     6.3783819675446 seconds
preg_replace (NL):  5.8873070478439 seconds
preg_replace (L=3): 5.5973950624466 seconds
YMMV.

Acties:
  • 0 Henk 'm!

  • Burat
  • Registratie: Oktober 1999
  • Niet online

Burat

bos wortels

Het is sneller dan substr() ja. Maar vergelijk het eens met chunk_split. Dan is het ineens bijna 40% trager!

En in dit geval is de regexp nog redelijk snel. Zie onderaan de post trouwens voor een APD Trace.

De regel voor een regexp is over het algemeen:
-> Als je moet kiezen tussen een regexp en een zelf geschreven PHP Functie is een regexp sneller
-> Als je kan kiezen tussen een regexp en een andere PHP Functie die hetzelfde kan, is de andere PHP Functie sneller.

De preg_replace is intern namelijk wel een mooie C-functie in Zend (en geen extension):
PHP:
1
2
3
4
5
6
7
8
9
<?php

$string = "00001ad3b32fdd596d31283800000000";

$splitted_string = preg_replace("/(.{8})/", "\\1 ", $string);

echo $splitted_string;

?>

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Bert Slagter@bert-laptop /usr/src/php-4.3.4
$ ./sapi/cli/php ./test.php
Class stdClass: [no user functions]
Class __PHP_Incomplete_Class: [no user functions]
Class Directory: [no user functions]
filename:       /usr/src/php-4.3.4/test.php
function name:  (null)
number of ops:  12
line     #  op                   fetch  ext  operands
-------------------------------------------------------------------------------
   3     0  FETCH_W                          $0, 'string'
         1  ASSIGN                           $0, '00001ad3b32fdd596d31283800000000'
   5     2  SEND_VAL                         '%2F%28.%7B8%7D%29%2F'
         3  SEND_VAL                         '%5C1+'
         4  FETCH_R                          $3, 'string'
         5  SEND_VAR                         $3
         6  DO_FCALL                      3  $4, 'preg_replace', 0
         7  FETCH_W                          $2, 'splitted_string'
         8  ASSIGN                           $2, $4
   7     9  FETCH_R                          $6, 'splitted_string'
        10  ECHO                             $6
  10    11  RETURN                           1

00001ad3 b32fdd59 6d312838 00000000

Dit is trouwens gemaakt met de "Vulcan Logic Disassambler" van Derrick Rethans (Een nederlandse PHP devver).

test3.php
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
<?php

apd_set_pprof_trace();
$string = "00001ad3b32fdd596d31283800000000";

for($i=0; $i < 10000; $i++)
{       $splitted_string = preg_replace("/(.{8})/", "\\1 ", $string);
}

echo $splitted_string;

?>


code:
1
2
3
4
5
6
7
8
9
10
11
Trace for /home/bslagter/test/test3.php
Total Elapsed Time =    0.35
Total System Time  =    0.01
Total User Time    =    0.34


         Real         User        System             secs/    cumm
%Time (excl/cumm)  (excl/cumm)  (excl/cumm) Calls    call    s/call  Memory Usage Name
--------------------------------------------------------------------------------------
100.0  0.35  0.35   0.34  0.34   0.01  0.01  10000   0.0000    0.0000            0 preg_replace
  0.0  0.00  0.00   0.00  0.00   0.00  0.00     1   0.0000    0.0000            0 main

[ Voor 3% gewijzigd door Burat op 10-11-2003 11:33 ]

Homepage | Me @ T.net | Having fun @ Procurios | Collega's gezocht: Webontwikkelaar PHP


Acties:
  • 0 Henk 'm!

Verwijderd

Burat: Het is sneller dan substr() ja.
substr() zou veel, véél, sneller moeten zijn dan de regex in dit soort gevallen, maar ik weet uit ervaring dat dat niet zo is. (Bijvoorbeeld in Perl is de substr oplossing zo'n vier keer zo snel als een regex, zoals je zou verwachten.)
Maar vergelijk het eens met chunk_split. Dan is het ineens bijna 40% trager!
De kwaliteit van de string functies in PHP is heel wisselend, en dan vertrouw ik liever op de PCRE dan te moeten onthouden dat in dit specifieke geval chunk_split een stuk sneller is (net als word_wrap?), maar substr weer langzamer. Er zijn meer dan 80 string functies...
De preg_replace is intern namelijk wel een mooie C-functie in Zend (en geen extension).
Hm? Bij jou is ext/pcre leeg? :?

Acties:
  • 0 Henk 'm!

  • stekkel
  • Registratie: Augustus 2001
  • Laatst online: 17-09 08:05
Verwijderd schreef op 10 november 2003 @ 13:04:
[...]
substr() zou veel, véél, sneller moeten zijn dan de regex in dit soort gevallen, maar ik weet uit ervaring dat dat niet zo is. (Bijvoorbeeld in Perl is de substr oplossing zo'n vier keer zo snel als een regex, zoals je zou verwachten.)
Je vergeet een ding, een functie aanroep kost ook tijd. In geval van substr gaat het om 4 functie aanroepen. Daarnaast is concatinatie van strings in php traag. In geval van de substr oplossing gebeurd dat 3 x.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Het is natuurlijk niet de functieaanroep dat het zoveel trager maakt, dat is verwaarloosbaar. Waar het om gaat is dat er 4x een concat gedaan moet worden (wat dus sowieso al 4x een bufferallocatie betekent) zoals je al zei, maar ook dat voor elke keer dat substr wordt aangeroepen ook nog eens een buffer gealloceerd moet worden

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.

Pagina: 1