[perl] Aanral hoofdletters in string tellen

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Tjark
  • Registratie: Juni 2000
  • Laatst online: 15-09 11:50

Tjark

DON'T PANIC

Topicstarter
Hoi,

Weet iemand toevallig een handige manier om het aantal hoofdletters in een string te tellen?
Ik heb nu dit:
code:
1
2
$count=0;
while($string=~/[A-Z]/g) { $count++};

En dat werkt prima, maar ben gewoon nieuwsgierig :)

*insert signature here


Acties:
  • 0 Henk 'm!

  • stylee
  • Registratie: December 2000
  • Laatst online: 04-09-2021

stylee

blah zeg ik je

* stylee vraagt zich af waar Arien blijft >:)

Acties:
  • 0 Henk 'm!

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 11-09 11:19

chem

Reist de wereld rond

preg_match_all("/[A-Z]/s", $string, $matches)
sizeof($matches); ( * )

 


 


( * ) batteries en testing not included

Klaar voor een nieuwe uitdaging.


Acties:
  • 0 Henk 'm!

  • Annie
  • Registratie: Juni 1999
  • Laatst online: 25-11-2021

Annie

amateur megalomaan

Op donderdag 26 juli 2001 17:20 schreef chem het volgende:
preg_match_all("/[A-Z]/s", $string, $matches)
sizeof($matches); ( * )

( * ) batteries en testing not included
<flauw>
php != perl
</flauw>

het gaat zeker om idee ;)

Today's subliminal thought is:


Acties:
  • 0 Henk 'm!

  • Tjark
  • Registratie: Juni 2000
  • Laatst online: 15-09 11:50

Tjark

DON'T PANIC

Topicstarter
haha.... idd :)

'k werk de laatste tijd idd wat meer met php dan perl en dan merk je af en toe wel dat php standaard net wat meer functies heeft.

Maar ik hoopte dat een perl-wizzard misschien nog een leukere manier wist.

*insert signature here


Acties:
  • 0 Henk 'm!

  • stylee
  • Registratie: December 2000
  • Laatst online: 04-09-2021

stylee

blah zeg ik je

wacht maar tot Arien online komt >:) >:) >:)

Acties:
  • 0 Henk 'm!

Verwijderd

Dit is al wat korter (en waarschijnlijk sneller), maar die tr// kan vast nog wel beter:
code:
1
2
$stringetje = "gOeDeMoRgEn";
$amount = $stringetje =~ tr/[A-Z]/[A-Z]/;

Acties:
  • 0 Henk 'm!

  • Tjark
  • Registratie: Juni 2000
  • Laatst online: 15-09 11:50

Tjark

DON'T PANIC

Topicstarter
ffetjes 1000000 keer getest;
While loop: 53sec
tr//: 17sec

:)

*insert signature here


Acties:
  • 0 Henk 'm!

  • Annie
  • Registratie: Juni 1999
  • Laatst online: 25-11-2021

Annie

amateur megalomaan

Op donderdag 26 juli 2001 21:30 schreef Sneech het volgende:
Dit is al wat korter (en waarschijnlijk sneller), maar die tr// kan vast nog wel beter:
code:
1
2
$stringetje = "gOeDeMoRgEn";
$amount = $stringetje =~ tr/[A-Z]/[A-Z]/;
tr// ietsjes korter:
code:
1
2
$stringetje = "gOeDeMoRgEn";
$amount = $stringetje =~ tr/[A-Z]//;

Today's subliminal thought is:


Acties:
  • 0 Henk 'm!

  • Tjark
  • Registratie: Juni 2000
  • Laatst online: 15-09 11:50

Tjark

DON'T PANIC

Topicstarter
check: 12 secs :)

*insert signature here


Acties:
  • 0 Henk 'm!

Verwijderd

TjarkVerhoeven: Weet iemand toevallig een handige manier om het aantal hoofdletters in een string te tellen?
Je hebt al een efficiente manier gekregen. :)
stylee: * stylee vraagt zich af waar Arien blijft >:)
Die lag te slapen toen jij dat postte. :Z
chem: preg_match_all("/[A-Z]/s", $string, $matches)
Waarom /s ? :?
TjarkVerhoeven: 'k werk de laatste tijd idd wat meer met php dan perl en dan merk je af en toe wel dat php standaard net wat meer functies heeft.
En net wat minder modules. ;)
Ik hoopte dat een perl-wizzard misschien nog een leukere manier wist.
Het kan op zoveel manieren maar met tr// is wel zo efficient denk ik.
stylee: Wacht maar tot Arien online komt >:) >:) >:)
:Z ... en maar wachten... :Z :P
Sneech: Dit is al wat korter (en waarschijnlijk sneller)
Is een factor 7 sneller.
Die tr// kan vast nog wel beter.
Die kan beter ja: >:)
code:
1
$amount = $string =~ tr/A-Z/A-Z/;

(Zie het gebrek aan [...]-jes.)

edit: En toen begon het back-up script of was mijn verbinding brak? :(

Acties:
  • 0 Henk 'm!

Verwijderd

Oh ja, dan wil je natuurlijk weten hoe ik getest heb:
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
27
#!/usr/bin/perl

use strict;
use warnings;
use Benchmark;

undef $/;
my $string = <STDIN>;

my %test = (
    tr => sub {
      my $count = ($string =~ tr/A-Z/A-Z/);
    },
    tr_strip  => sub {
      my $count = ($string =~ tr/A-Z//);
    },
    m  => sub {
      my $count = 0;
      $count++ while ($string =~ /[A-Z]/g);
    }
);

my $reps = 10000;
foreach(keys %test) {
    my $runtime = timeit($reps, $test{$_});
    print "$_: $reps loops took ", timestr($runtime), "\n";
}

Gebruiken als:
code:
1
perl caps.pl < grootTextBestand

Edit:
Natuurlijk wel even de uitslag erbij zetten. |:(
tr_strip (deze: tr/A-Z//) is het snelst.

Acties:
  • 0 Henk 'm!

  • Tjark
  • Registratie: Juni 2000
  • Laatst online: 15-09 11:50

Tjark

DON'T PANIC

Topicstarter
Arien: bij mij is
tr/[A-Z]//
sneller dan
tr/A-Z//

*insert signature here


Acties:
  • 0 Henk 'm!

Verwijderd

TjarkVerhoeven: Bij mij is tr/[A-Z]// sneller dan tr/A-Z//
Maar het telt wat anders.

tr werkt met tekens niet met regexen (en dus ook niet met character classes).
Dus wat je nu telt zijn alle hoofdletters en [ of ].

Acties:
  • 0 Henk 'm!

Verwijderd

Even een voorbeeld zodat je het probleem ziet:
code:
1
2
3
4
$_ = "Dit is wat tekst met HOOFDletters en ook []";

print "Fout: ", tr/[A-Z]//, "\n";
print "Goed: ", tr/A-Z//;

Output:
code:
1
2
Fout: 8
Goed: 6

Acties:
  • 0 Henk 'm!

  • Tjark
  • Registratie: Juni 2000
  • Laatst online: 15-09 11:50

Tjark

DON'T PANIC

Topicstarter
ah.. check, thanx

*insert signature here


Acties:
  • 0 Henk 'm!

  • Annie
  • Registratie: Juni 1999
  • Laatst online: 25-11-2021

Annie

amateur megalomaan

Op vrijdag 27 juli 2001 10:33 schreef Arien het volgende:

[..]

Maar het telt wat anders.

tr werkt met tekens niet met regexen (en dus ook niet met character classes).
Dus wat je nu telt zijn alle hoofdletters en [ of ].
:o hehe, oeps :o
krijg je ervan als je niet netjes in de ref kijkt hoe het ook weer zat, maar de reply erboven quote. |:(

* Annie kruipt stilletjes weg in een hoekje om zich te schamen

Today's subliminal thought is:


Acties:
  • 0 Henk 'm!

Verwijderd

Annie: Krijg je ervan als je niet netjes in de ref kijkt hoe het ook weer zat, maar de reply erboven quote. |:(
<off-topic>

Het is heel simpel te onthouden: tr staat voor transliterate en is dus tekens door andere tekens vervangen (met erg de nadruk op tekens). :)

In het geval van tr/A-Z// wordt er dus niets aan je string vervangen omdat er rechts geen vervangende tekens staan. Als je gevonden tekens die niet vervangen zijn wel wilt weghalen kan dat met tr/A-Z//d.

</off-topic>

Acties:
  • 0 Henk 'm!

Verwijderd

Op zaterdag 28 juli 2001 16:30 schreef Arien het volgende:

[..]
In het geval van tr/A-Z// wordt er dus niets aan je string vervangen omdat er rechts geen vervangende tekens staan.
[..]
Je zou het als onwetende (zoals ik :)) ook kunnen opvatten als: er zijn geen vervangende karakters, dus de gematch'te chars worden gewoon verwijderd.

Acties:
  • 0 Henk 'm!

Verwijderd

Sneech: Je zou het als onwetende (zoals ik :)) ook kunnen opvatten als: er zijn geen vervangende karakters, dus de gematch'te chars worden gewoon verwijderd.
Je beschrijft wat er met de /d modifier gebeurt, maar dat is niet de default.

Als er geen lijst vervangende tekens is, wordt (behalve als je de /d modifier gebruikt) de lijst tekens waarop je zoekt genomen als de lijst vervangende tekens.

In het algemeen is het zo dat als de lijst vervangende tekens korter is dan de lijst tekens waarop je zoekt het laatste teken van de lijst vervangende tekens net zo vaak herhaald wordt als nodig is.
code:
1
2
tr/A-Z//;  # tr/A-Z/A-Z/;
tr/A-Z/*/; # tr/A-Z/**************************/;

Als je de /d modifier gebruikt geldt dit niet en worden tekens die geen corrresponderend teken hebben in de lijst vervangende tekens verwijderd.

Acties:
  • 0 Henk 'm!

Verwijderd

Hehe, mn Perl-kennis begint duidelijk alweer te vervagen :)
Pagina: 1