'\U21b4'
'↴': Unicode U+21B4 (category So: Symbol, other)
Es gab - abhängig von Hersteller, Land, Programmiersprache, Betriebsssystem,… - eine große Vielzahl von Codierungen.
Bis heute relevant sind:
Der American Standard Code for Information Interchange wurde 1963 in den USA als Standard veröffentlicht.
newline
, escape
, end of transmission/file
, delete
a-z, A-Z
0-9
.,:;?!"
[{()}]
+-*/<>=
#$%&'\^_|~`@
Codierung | Region | Sprachen |
---|---|---|
ISO 8859-1 (Latin-1) | Westeuropa | Deutsch, Französisch,…,Isländisch |
ISO 8859-2 (Latin-2) | Osteuropa | slawische Sprachen mit lateinischer Schrift |
ISO 8859-3 (Latin-3) | Südeuropa | Türkisch, Maltesisch,… |
ISO 8859-4 (Latin-4) | Nordeuropa | Estnisch, Lettisch, Litauisch, Grönländisch, Sami |
ISO 8859-5 (Latin/Cyrillic) | Osteuropa | slawische Sprachen mit kyrillischer Schrift |
ISO 8859-6 (Latin/Arabic) | ||
ISO 8859-7 (Latin/Greek) | ||
… | ||
ISO 8859-15 (Latin-9) | 1999: Revision von Latin-1: jetzt u.a. mit Euro-Zeichen |
Das Ziel des Unicode-Consortiums ist eine einheitliche Codierung für alle Schriften der Welt.
codepoint
zugeordnet. Das ist einfach eine fortlaufende Nummer.U+XXXX
(0-te Ebene)U+XXXXXX
(weitere Ebenen)U+XY0000
bis U+XYFFFF
, kann also \(2^{16}=65\;534\) Zeichen enthalten.XY=00
bis XY=10
, also der Wertebereich von U+0000
bis U+10FFFF
.U+0000 - U+FFFF
,U+010000 - U+01FFFF
,U+020000 - U+02FFFF
,U+030000 - U+03FFFF
undU+0E0000 - U+0EFFFF
vergeben.U+0000
bis U+007F
ist identisch mit ASCIIU+0000
bis U+00FF
ist identisch mit ISO 8859-1 (Latin-1)Im Standard wird jedes Zeichen beschrieben duch
Im Unicode-Standard sieht das dann so aus (zur Vereinfachung nur Codepoint und Name):
...
U+0041 LATIN CAPITAL LETTER A
U+0042 LATIN CAPITAL LETTER B
U+0043 LATIN CAPITAL LETTER C
U+0044 LATIN CAPITAL LETTER D
...
U+00E9 LATIN SMALL LETTER E WITH ACUTE
U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX
...
U+0641 ARABIC LETTER FEH
U+0642 ARABIC LETTER QAF
...
U+21B4 RIGHTWARDS ARROW WITH CORNER DOWNWARDS
...
Wie sieht ‘RIGHTWARDS ARROW WITH CORNER DOWNWARDS’ aus?
Julia verwendet \U...
zur Eingabe von Unicode Codepoints.
'\U21b4'
'↴': Unicode U+21B4 (category So: Symbol, other)
Falls im Folgenden einzelne Zeichen oder Schriften in Ihrem Browser nicht darstellbar sind, müssen Sie geeignete Fonts auf Ihrem Rechner installieren.
Alternativ können Sie die PDF-Version dieser Seite verwenden. Dort sind alle Fonts eingebunden.
Eine kleine Hilfsfunktion:
function printuc(c, n)
for i in 0:n-1
print(c + i)
end
end
printuc (generic function with 1 method)
Kyrillisch
printuc('\U0400', 100)
ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓєѕіїјљњћќѝўџѠѡѢѣ
Tamilisch
printuc('\U0be7',20)
௧௨௩௪௫௬௭௮௯௰௱௲௳௴௵௶௷௸௹௺
Schach
printuc('\U2654', 12)
♔♕♖♗♘♙♚♛♜♝♞♟
Mathematische Operatoren
printuc('\U2200', 255)
∀∁∂∃∄∅∆∇∈∉∊∋∌∍∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡∢∣∤∥∦∧∨∩∪∫∬∭∮∯∰∱∲∳∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝≞≟≠≡≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾
Runen
printuc('\U16a0', 40)
ᚠᚡᚢᚣᚤᚥᚦᚧᚨᚩᚪᚫᚬᚭᚮᚯᚰᚱᚲᚳᚴᚵᚶᚷᚸᚹᚺᚻᚼᚽᚾᚿᛀᛁᛂᛃᛄᛅᛆᛇ
Scheibe (Diskus) von Phaistos
printuc('\U101D0', 46 )
𐇐𐇑𐇒𐇓𐇔𐇕𐇖𐇗𐇘𐇙𐇚𐇛𐇜𐇝𐇞𐇟𐇠𐇡𐇢𐇣𐇤𐇥𐇦𐇧𐇨𐇩𐇪𐇫𐇬𐇭𐇮𐇯𐇰𐇱𐇲𐇳𐇴𐇵𐇶𐇷𐇸𐇹𐇺𐇻𐇼𐇽
Unicode transformation formats legen fest, wie eine Folge von Codepoints als eine Folge von Bytes dargestellt wird.
Da die Codepoints unterschiedlich lang sind, kann man sie nicht einfach hintereinander schreiben. Wo hört einer auf und fängt der nächste an?
Für jeden Codepoint werden 1, 2, 3 oder 4 volle Bytes verwendet.
Bei einer Codierung mit variabler Länge muss man erkennen können, welche Bytefolgen zusammengehören:
Damit ist der Platz, der für den Codepoint zur Verfügung steht (Anzahl der x):
Damit ist jeder ASCII-Text automatisch auch ein korrekt codierter UTF-8-Text.
Sollten die bisher für Unicode festgelegten 17 Ebenen (= 21 Bit = 1.1 Mill. mögliche Zeichen) mal erweitert werden, dann wird UTF-8 auf 5- und 6-Byte-Codes erweitert.
Char
Der Datentyp Char
kodiert ein einzelnes Unicode-Zeichen.
'a'
.Char
belegt 4 Bytes Speicher undChar
s können von/zu UInt
s umgewandelt werden undChar
s können von/zu UInt
s umgewandelt werden.
UInt('a')
0x0000000000000061
= Char(0x2656) b
'♖': Unicode U+2656 (category So: Symbol, other)
String
"a"
.@show typeof('a') sizeof('a') typeof("a") sizeof("a");
typeof('a') = Char
sizeof('a') = 4
typeof("a") = String
sizeof("a") = 1
Bei einem Nicht-ASCII-String unterscheiden sich Anzahl der Bytes und Anzahl der Zeichen:
= "Hello World!"
asciistr @show length(asciistr) ncodeunits(asciistr);
length(asciistr) = 12
ncodeunits(asciistr) = 12
(Das Leerzeichen zählt natürlich auch.)
= "😄 Hellö 🎶"
str @show length(str) ncodeunits(str);
length(str) = 9
ncodeunits(str) = 16
Iteration über einen String iteriert über die Zeichen:
for i in str
println(i, " ", typeof(i))
end
😄 Char
Char
H Char
e Char
l Char
l Char
ö Char
Char
🎶 Char
“Strings mit Verkettung bilden ein nichtkommutatives Monoid.”
Deshalb wird in Julia die Verkettung multiplikativ geschrieben.
* asciistr * str str
"😄 Hellö 🎶Hello World!😄 Hellö 🎶"
Damit sind auch Potenzen mit natürlichem Exponenten definiert.
^3, str^0 str
("😄 Hellö 🎶😄 Hellö 🎶😄 Hellö 🎶", "")
Das Dollarzeichen hat in Strings eine Sonderfunktion, die wir schon oft in print()
-Anweisungen genutzt haben. MAn kann damit eine Variable oder einen Ausdruck interpolieren:
= 33.4
a = "x"
b
= "Das Ergebnis für $b ist gleich $a und die verdoppelte Wurzel daraus ist $(2sqrt(a))\n" s
"Das Ergebnis für x ist gleich 33.4 und die verdoppelte Wurzel daraus ist 11.55854662143991\n"
Der backslash \
hat in Stringkonstanten ebenfalls eine Sonderfunktion. Julia benutzt die von C und anderen Sprachen bekannten backslash-Codierungen für Sonderzeichen und für Dollarzeichen und Backslash selbst:
= "So bekommt man \'Anführungszeichen\" und ein \$-Zeichen und einen\nZeilenumbruch und ein \\ usw... "
s print(s)
So bekommt man 'Anführungszeichen" und ein $-Zeichen und einen
Zeilenumbruch und ein \ usw...
Man kann Strings auch mit Triple-Quotes begrenzen. In dieser Form bleiben Zeilenumbrüche und Anführungszeichen erhalten:
= """
s Das soll
ein "längerer"
'Text' sein.
"""
print(s)
Das soll
ein "längerer"
'Text' sein.
In einem raw string
sind alle backslash-Codierungen außer \"
abgeschaltet:
= raw"Ein $ und ein \ und zwei \\ und ein 'bla'..."
s print(s)
Ein $ und ein \ und zwei \\ und ein 'bla'...
@show isdigit('0') isletter('Ψ') isascii('\U2655') islowercase('α')
@show isnumeric('½') iscntrl('\n') ispunct(';');
isdigit('0') = true
isletter('Ψ') = true
isascii('♕') = false
islowercase('α') = true
isnumeric('½') = true
iscntrl('\n') = true
ispunct(';') = true
Diese Tests lassen sich z.B. mit all()
, any()
oder count()
auf Strings anwenden:
all(ispunct, ";.:")
true
any(isdigit, "Es ist 3 Uhr! 🕒" )
true
count(islowercase, "Hello, du!!")
6
@show startswith("Lampenschirm", "Lamp") occursin("pensch", "Lampenschirm")
@show endswith("Lampenschirm", "irm");
startswith("Lampenschirm", "Lamp") = true
occursin("pensch", "Lampenschirm") = true
endswith("Lampenschirm", "irm") = true
@show uppercase("Eis") lowercase("Eis") titlecase("eiSen");
uppercase("Eis") = "EIS"
lowercase("Eis") = "eis"
titlecase("eiSen") = "Eisen"
# remove newline from end of string
@show chomp("Eis\n") chomp("Eis");
chomp("Eis\n") = "Eis"
chomp("Eis") = "Eis"
split("π ist irrational.")
3-element Vector{SubString{String}}:
"π"
"ist"
"irrational."
replace("π ist irrational.", "ist" => "ist angeblich")
"π ist angeblich irrational."
Strings sind nicht mutierbar aber indizierbar. Dabei gibt es ein paar Besonderheiten.
Unser Beispielstring:
str
"😄 Hellö 🎶"
Das erste Zeichen
1] str[
'😄': Unicode U+1F604 (category So: Symbol, other)
Dieses Zeichen ist in UTF8-Kodierung 4 Bytes lang. Damit sind 2,3 und 4 ungültige Indizes.
2] str[
StringIndexError: invalid index [2], valid nearby indices [1]=>'😄', [5]=>' '
Stacktrace:
[1] string_index_err(s::String, i::Int64)
@ Base ./strings/string.jl:12
[2] getindex_continued(s::String, i::Int64, u::UInt32)
@ Base ./strings/string.jl:472
[3] getindex(s::String, i::Int64)
@ Base ./strings/string.jl:464
[4] top-level scope
@ ~/Julia/23/Book-ansipatch/chapters/10_Strings.qmd:469
Erst das 5. Byte ist ein neues Zeichen:
5] str[
' ': ASCII/Unicode U+0020 (category Zs: Separator, space)
Auch bei der Adressierung von Substrings müssen Anfang und Ende jeweils gültige Indizes sein, d.h., der Endindex muss ebenfalls das erste Byte eines Zeichens indizieren und dieses Zeichen ist das letzte des Teilstrings.
1:7] str[
"😄 He"
Die Funktion eachindex()
liefert einen Iterator über die gültigen Indizes:
for i in eachindex(str)
= str[i]
c println("$i: $c")
end
1: 😄
5:
6: H
7: e
8: l
9: l
10: ö
12:
13: 🎶
Wie üblich macht collect() aus einem Iterator einen Vektor.
collect(eachindex(str))
9-element Vector{Int64}:
1
5
6
7
8
9
10
12
13
Die Funktion nextind()
liefert den nächsten gültigen Index.
@show nextind(str, 1) nextind(str, 2);
nextind(str, 1) = 5
nextind(str, 2) = 5
Warum verwendet Julia einen Byte-Index und keinen Zeichenindex? Der Hauptgrund dürfte die Effizienz der Indizierung sein.
s[123455]
mit einem Byte-Index schnell zu finden.Einige Funktionen liefern Indizes oder Ranges als Resultat. Sie liefern immer gültige Indizes:
findfirst('l', str)
8
findfirst("Hel", str)
6:8
= "αβγδϵ"^3 str2
"αβγδϵαβγδϵαβγδϵ"
= findfirst('γ', str2) n
5
So kann man ab dem nächsten nach n=5
gültigen Index weitersuchen:
findnext('γ', str2, nextind(str2, n))
15