Mit Perl den ASCII-Wert eines Zeichens ändern
Johannes Weißl
- perl
0 Cheatah
Hallo,
Wie kann man mit Perl den ASCII-Wert eines Zeichens ändern?
(z.B. um A hat den Wert 65 und dieser Wert soll um 5 nach unten gesetzt werden und dieser Wert, also 60, soll wieder in ein Zeichen verwandelt werden!)
cu,
Johannes
Hi,
Wie kann man mit Perl den ASCII-Wert eines Zeichens ändern?
wie lange hast Du Zeit, um Dir alle Möglichkeiten anzuhören?
(z.B. um A hat den Wert 65 und dieser Wert soll um 5 nach unten gesetzt werden und dieser Wert, also 60, soll wieder in ein Zeichen verwandelt werden!)
$string =~ s/A/chr(60)/eg;
Je nach Anforderungen tun es auch substr, tr///, pack usw. Schau in der Doku zum jeweiligen Befehl nach.
Cheatah
Hi,
$string =~ s/A/chr(60)/eg;
viel zu statisch, besser so in der Richtung:
$string =~ s/(.)/chr(ord($1)-5)/eg;
mfg
CK1
Hallo
$string =~ s/A/chr(60)/eg;
viel zu statisch, besser so in der Richtung:
$string =~ s/(.)/chr(ord($1)-5)/eg;
mag sein, aber verstehen, wenn man bei regexpr. das überhaupt sagen kann ;-) tut man cheatahs Version am ehesten! Bei deiner steigt jeder nicht-auch-nur-halbwegs-perl-Profi wie ich leider voll aus :-(
Dazu müsste man erst mal wissen, was (.) matcht (Irgendein einzelnes Zeichen?)
und was in $1 drinnenliegt (der gematchte Asudruck??)
... dann könnte ich mir daraus einen halbwegs sinnvollen ;-) Reim machen!
Übrigens, an welcher Ascii-Tabelle orientiert sich Perl, wenn man chr(xxx) aufruft? Da sind ja die Zeichenbelegungen ziemlich unterschiedlich, zumindest bei den Sonderzeichen! Gibts da einen Standardzeichensatz?
liebe Grüsse und,
keep it simple ;-)
Bernhard
Hi,
$string =~ s/(.)/chr(ord($1)-5)/eg;
mag sein, aber verstehen, wenn man bei regexpr. das überhaupt sagen kann ;-) tut man cheatahs Version am ehesten!
Christians Lösung ist nur eine kleine Verallgemeinerung der meinen.
Bei deiner steigt jeder nicht-auch-nur-halbwegs-perl-Profi wie ich leider voll aus :-(
Schon der nicht-mehr-ganz-so-Perl-Anfänger kann in der Doku nachschlagen, was die einzelnen Teile bedeuten. Es mag zwar ein paar Minuten brauchen, bis Du diese RegExp verstehst, aber ein Geheimnis - oder auch nur kompliziert - ist sie nicht.
Dazu müsste man erst mal wissen, was (.) matcht (Irgendein einzelnes Zeichen?)
und was in $1 drinnenliegt (der gematchte Asudruck??)
Beides erfährst Du erstens in perldoc perlre, und sind zweitens die Grundlagen im Umgang mit Regular Expressions. Ebenso wie die Bedeutung des Parameters /e.
Übrigens, an welcher Ascii-Tabelle orientiert sich Perl, wenn man chr(xxx) aufruft?
Es gibt nur eine ASCII-Tabelle. Das "S" steht für "Standard".
Da sind ja die Zeichenbelegungen ziemlich unterschiedlich, zumindest bei den Sonderzeichen!
Bei allen nicht-ASCII-Zeichen siehst Du die Belegung, wenn Du mal kurz
for (128..255) {
print $_, "\t", chr($_), "\n";
}
auf die Konsole ausgeben läßt.
Cheatah
Hi Bernhard!
viel zu statisch, besser so in der Richtung:
$string =~ s/(.)/chr(ord($1)-5)/eg;mag sein, aber verstehen, wenn man bei regexpr. das überhaupt sagen kann ;-) tut man cheatahs Version am ehesten!
Der Unterschied ist, dass Christians Version von *jedem* Zeichen 5 abziehen kann, nicht nur vom A.
Dazu müsste man erst mal wissen, was (.) matcht (Irgendein einzelnes Zeichen?)
und was in $1 drinnenliegt (der gematchte Asudruck??)
Da gebe ich Cheatah recht, das sind wirklich die elementaren Grundlagen der RegExpe, aber Dein Gefuehl hat Dich ja schon in die richtige Richtung gefuehrt. Bleibt noch zu erwaehnen, dass das e nach dem letzten / bedeutet, dass der Ersetzungsausdruck keine Zeichenkette ist, sondern als Perl-Statement ausgewertet wird. Aber das hats Du Dir sicher auch schon gedacht oder - noch besser - mittlerweile in perlre (diesmal ohne f *g*) gelesen. ;-)
Übrigens, an welcher Ascii-Tabelle orientiert sich Perl, wenn man chr(xxx) aufruft? Da sind ja die Zeichenbelegungen ziemlich unterschiedlich, zumindest bei den Sonderzeichen! Gibts da einen Standardzeichensatz?
An gar keiner. Letztlich sind im Computer nur Zahlen drin und keine Zeichen. Und auch nach der Umwandlung mit chr() steht im Speicher in Wirklichkeit eine Zahl (dieselbe wie vorher), nur Perl weiss jetzt, dass es diesen Skalar als Zeichen behandeln soll und nicht als Zahl. Erst bei einer Ausgabe auf dem Bildschirm wird die in genau diesem Moment aktive Zeichentabelle verwendet, um das zu der Zahl zugehoerige Zeichen herauszusuchen. Wenn die Bildschirmausgabe auf der Console erfolgt, wird eben der Font der Console verwendet, werden die Zeichen aber zu einem Browser geschickt, wird eben die auf dem Client-Rechner aktive Zeichentabelle verwendet (welche sich in HTML wiederum durch ein META-Tag beeinflussen laesst).
(Tatsaechlich gibt es nur eine echte (US-)ASCII-Tabelle, die nur aus den Zeichen 0 bis 127 besteht. Alles was danach kommt, sind andere Zeichensaetze nach irgendeiner Norm, z.B. iso-8859-1.)
So long
Hallo Calocybe
Da gebe ich Cheatah recht, das sind wirklich die elementaren
Grundlagen der RegExp,
Ja, gut, ich glaubs ja, tut mir leid so blöd gefragt zu haben, aber
ich vermeide RegExpr so gut es geht, da wird mein armes kleines
Köpfchen immer so beansprucht, wenn ich mir zusammenreimen muss, wie
ich das hindrehen kann, dass man mit möglichst wenig wirr
arrangierten Zeichen nach einem Wort suchen kann. Echt, da lauf ich
immer heiss, vielleich denke ich ja zu kompliziert, aber ich krieg
da nie den Ausdruck zustande, der genau das macht was ich will!
aber Dein Gefuehl hat Dich ja schon in die richtige Richtung
gefuehrt. Bleibt noch zu erwaehnen, dass das e nach dem letzten /
bedeutet, dass der Ersetzungsausdruck keine Zeichenkette ist,
sondern als Perl-Statement ausgewertet wird. Aber das hats Du Dir
sicher auch schon gedacht oder - noch besser - mittlerweile in
perlre (diesmal ohne f *g*) gelesen. ;-)
Danke, dass du es mir dennoch erklärt hast! Und ich hätte da auch
gleich mal nen Vorschlag: Du kennst doch sicher die "Glücksspirale"
von SAT1 oder? Da können Leute, die vor irgendwas (z.B.: Spinnen,..)
panische Angst haben, wenn sie ihre Furcht überwinden, tolle Preise
gewinnen! -Dort könnte ich mich anmelden. Ich lese vor laufender
Kamera das gesamte perldoc perlre durch, von oben bis unten, ohne
Absetzen ;-) Und als Preis würde ich vorschlagen: einen Tag mit dem
Genie das PERL "erfunden" hat zu verbringen, damit ich dann mein
frisch erworbenes Wissen gleich an den Mann bringen kann. Der kann
sicher stundenlang über Reguläre Ausdrücke schwafeln ! Na, und ich
dann ja auch ;-)
Oder ich zieh mich in eine einsame Hütte in irgendeinem abgelegenen
Waldstück zurück, und zieh sie mir dort rein. Da kann mich keiner
sehen, wenn ich mich meinem Leiden ergebe, und dem Wahnsinn näher
als ein ganzes "Irrenhaus" von einer Ecke in die andere laufe und
nur noch wirre Wörter stammle:
"s...slash...backslash..s..nein..n..dann..oder.. oder nicht...oder
und...nein t....blödsinn...slash...eckige klammer
auf...dann....punkt..."
jetzt muss ich sogar selbst ein wenig *grinsen*
Erst bei einer Ausgabe auf dem Bildschirm wird die in genau
diesem Moment aktive Zeichentabelle verwendet, um das zu der Zahl
zugehoerige Zeichen herauszusuchen. Wenn die Bildschirmausgabe
auf der Console erfolgt, wird eben der Font der Console
verwendet, werden die Zeichen aber zu einem Browser geschickt,
wird eben die auf dem Client-Rechner aktive Zeichentabelle
verwendet (welche sich in HTML wiederum durch ein META-Tag
beeinflussen laesst).
Das war jetzt aufschlussreich, danke, ich glaube es hat gefruchtet!
(Tatsaechlich gibt es nur eine echte (US-)ASCII-Tabelle, die nur
aus den Zeichen 0 bis 127 besteht. Alles was danach kommt, sind
andere Zeichensaetze nach irgendeiner Norm, z.B. iso-8859-1.)
huch, und was passiert jetzt, ich spür so ein Kribbeln bei meinen
Füssen, ich glaube ... ja ... oh ... es hat nicht nur gefruchtet,
nein es schlägt auch schon Wurzeln ;-)
Ich hab bloss in div. Büchern oft 10 oder mehr verschiedene Ascii-
Tabellen gesehen, und daher hab ich mich auch schon immer gefragt,
wozu das Ding eigentlich _Standard_ heisst, wenns doch erst wieder
1000 verschiedene Versionen davon gibt! Naja, aber dass sich nur die
Zeichen 128-255 unterscheiden, da bin ich wiedermal nicht
dahintergestiegen, und gesagt hats mir auch keiner, bis zum heutigen
Tage !
So long
so lang hats gar nicht gedauert oder ?
liebe Grüsse
Bernhard
Hallo Cheatah,
$string =~ s/A/chr(60)/eg;
Das Problem ist, das ich nicht nur das A sondern jedes beliebige Zeichen herab oder herauf setzen muss!
cu,
Johannes
Hi,
$string =~ s/A/chr(60)/eg;
Das Problem ist, das ich nicht nur das A sondern jedes beliebige Zeichen herab oder herauf setzen muss!
immer gleich? Dann ist Christians Lösung vermutlich das, was Du suchst; auch wenn sie mit einigen Zeichen (< ASCII 5, > ASCII 250) Probleme haben könnte.
Es ist aber nicht Sinn und Zwecke des _Self_HTML-Forums, Dir hier fertige Lösungen zu präsentieren. Ich habe Dir drei potentielle Kandidaten für Dein Problem genannt; den Rest mußt Du selbst machen. Wenn Du an einer Stelle auf spezifische Probleme stößt, helfen wir Dir gerne weiter.
Cheatah
Hi,
auch wenn sie mit einigen Zeichen (< ASCII 5, > ASCII 250) Probleme haben könnte.
Eigentlich hatte ich _absichtlich_ nicht auf das Problem hingewiesen, damit er selber darauf kommt und
drüber nachdenkt.
Zu lösen ist das jedoch recht einfach mit
$string =~ s/(.)/chr((ord($1) > 250 ord($1) < 5) ? (ord($1) > 250 ? (ord($1) - 250) : (ord($1) + 250)) : (ord($1) - 5))/eg;
(Ich mag es, fies zu sein *gg*)
mfg
CK1
Moin!
$string =~ s/(.)/chr((ord($1) > 250 || ord($1) < 5) ? (ord($1) > 250 ? (ord($1) - 250) : (ord($1) + 250)) : (ord($1) - 5))/eg;
Mmh.. Du musst Dich schon entscheiden, ob Du nun 5 addieren oder subtrahieren willst. Fuer den Fall der Subtraktion schlage ich diese kleine Optimierung vor (untested):
$string =~ s/(.)/chr((ord($1) + 256 - 5) & 0xFF)/eg;
(Die Addition von 256 soll einen Unterlauf unter 0 vermeiden. Normalerweise sollte das nicht noetig sein, aber wer weiss, was auf irgendeiner exotischen Plattform alles passieren kann.)
So long
Hi,
also erstmal: das Posting war nicht ganz ernst gemeint ;)
$string =~ s/(.)/chr((ord($1) > 250 ord($1) < 5) ? (ord($1) > 250 ? (ord($1) - 250) : (ord($1) + 250)) : (ord($1) - 5))/eg;
Mmh.. Du musst Dich schon entscheiden, ob Du nun 5 addieren oder subtrahieren willst.
hmpf, blöde Vorzeichenfehler... ich hab jetzt verquert gedacht, mit +5 und nicht -5 ;-)
also kann der Fall doch noch weiter vereinfacht werden:
$string =~ s/(.)/chr((ord($1) < 5) ? (ord($1) + 250)) : (ord($1) - 5))/eg;
Schade, es war so schön kompliziert ;-D
$string =~ s/(.)/chr((ord($1) + 256 - 5) & 0xFF)/eg;
oder eben so ;)
mfg
CK1
Hallo Cheatah,
immer gleich? Dann ist Christians Lösung vermutlich das, was Du suchst; auch wenn sie mit einigen Zeichen (< ASCII 5, > ASCII 250) Probleme haben könnte.
Nein, verschieden (z.B. in einer Schleife, um x wird immer dazugezählt und x wird am Ende jeder Schleife + 2 genommen!)
Es ist aber nicht Sinn und Zwecke des _Self_HTML-Forums, Dir hier fertige Lösungen zu präsentieren. Ich habe Dir drei potentielle Kandidaten für Dein Problem genannt; den Rest mußt Du selbst machen. Wenn Du an einer Stelle auf spezifische Probleme stößt, helfen wir Dir gerne weiter.
Nein, natürlich nicht. Jetzt da ich das mit dem chr() und ord() weiß (ist ja wie z.B. in Qbasic) weiß ich es eh ungefähr. Aber ich konnte in SelfHTML nichts finden und so dachte ich mir, vielleicht enthält Perl so eine Funktion nicht!
cu,
Johannes
Hi,
immer gleich?
Nein, verschieden (z.B. in einer Schleife, um x wird immer dazugezählt und x wird am Ende jeder Schleife + 2 genommen!)
(nebenbei: Bitte laß zwischen Zitat und eigenem Text eine Leerzeile; dann brauche ich nicht immer zu suchen, was denn jetzt eigentlich von Dir ist, danke!)
Wenn ich das richtig verstehe, ist zu einem Zeitpunkt t die Verschiebung für alle Zeichen gleich. Dann läßt sich die in diesem Thread gennante Lösung entsprechend verallgemeinern: $x statt 5.
Nein, natürlich nicht. Jetzt da ich das mit dem chr() und ord() weiß (ist ja wie z.B. in Qbasic) weiß ich es eh ungefähr. Aber ich konnte in SelfHTML nichts finden und so dachte ich mir, vielleicht enthält Perl so eine Funktion nicht!
Ich habe schon mehrfach - zu Stefans Leidwesen[1] ;-) - zum Ausdruck gebracht, was ich vom Perl-Kapitel in SelfHTML halte: Es ist in etwa so schlecht, wie die anderen Kapitel gut sind. Also mies. Du solltest es tunlichst vergessen und statt dessen die bei Perl mitgelieferte Doku verwenden. Linksetzer hat ja bereits seinen Job getan ;-) und einen Link auf eine Online-Version gesetzt; wenn Du Perl bei Dir installiert hast, bekommst Du aber das gleiche, indem Du auf Deinem System
perldoc perlfunc
eingibst. Mit
perldoc -f chr
bekommst Du dann beispielsweise die Doku zum Befehl chr.
Cheatah
[1] Ist aber nicht böse gemeint, Stefan, ich hoffe Du weißt das!