跳至內容

Introducing Julia/Strings and characters

維基教科書,自由的教學讀本


« Introducing Julia
Strings and characters
»
Dictionaries and sets Working with text files

Strings and characters

[編輯]

Strings

[編輯]

字符串是由一個或多個字符組成的序列,通常用雙引號括起來:

"this is a string"

關於字符串,有兩件重要的事情需要了解。


一個是,它們是不可變的。一旦它們被創建,你就不能改變它們。但是,從現有字符串的某些部分創建新字符串是很容易的。

第二點是,在使用兩個特定字符時必須小心:雙引號(")和美元符號($)。如果要在字符串中包含雙引號字符,則必須在其前面加上反斜槓,否則字符串的其餘部分將被解釋為 Julia 代碼,可能會產生有趣的結果。如果您想在字符串中包含一個美元符號($),也應該以反斜槓開頭,因為它用於字符串插值 string interpolation

julia> demand = "You owe me \$50!"
"You owe me \$50!"

julia> println(demand)
You owe me $50!
julia> demandquote = "He said, \"You owe me \$50!\""
"He said, \"You owe me \$50!\""

字符串也可以用三個雙引號括起來。這很有用,因為您可以在字符串中使用普通的雙引號,而不必在它們前面加反斜槓:

julia> """this is "a" string"""
"this is \"a\" string"

您還會遇到幾種特殊類型的字符串,這些字符串由一個或多個字符組成,後面緊跟着開頭的雙引號:

  • r" " 表示這是一個正則表達式
  • v" " 表示這是一個版本字符串
  • b" " 表示這是一個字節字面量
  • raw" " 表示這是一個 raw string 不允許插值

String interpolation

[編輯]

您通常希望在字符串中使用 Julia 表達式的結果。例如,假設您想說:

"The value of x is n."

nx 的當前值。任何 Julia 的表達式都可以插入到具有 $() 結構的字符串中:

julia> x = 42
42

julia> "The value of x is $(x)."
"The value of x is 42."

如果只是使用變量的名稱,則不必使用括號:

julia> "The value of x is $x."
"The value of x is 42."

若要將 Julia 表達式的結果包含在字符串中,請先將表達式括在括號中,然後在其前面加上一個美元符號:

julia> "The value of 2 + 2 is $(2 + 2)."
"The value of 2 + 2 is 4."

子字符串

[編輯]

若要從字符串中提取較小的字符串,請使用 getindex(s, range)s[range] 語法。對於基本ASCII字符串,可以使用用於從數組中提取元素的相同技術:

julia> s = String("a load of characters")
"a load of characters"

julia> s[1:end]
"a load of characters"

julia> s[3:6]
"load"
julia> s[3:end-6]
"load of char"

您可以輕鬆地遍歷字符串:

for char in s
    print(char, "_")
end
a_ _l_o_a_d_ _o_f_ _c_h_a_r_a_c_t_e_r_s_

注意,如果從字符串中提取單個元素,而不是長度為1的字符串(即具有相同的起始位置和結束位置):

julia> s[1:1]
"a" 

julia> s[1]
'a'

第二個結果不是字符串,而是一個字符(在單引號內)。

Unicode 字符串

[編輯]

並非所有字符串都是 ASCII。要訪問 Unicode 字符串中的單個字符,不能總是使用簡單索引,因為某些字符佔用多個索引位置。不要僅僅因為一些 index 看起來會起作用就被愚弄了:

julia> su = String("AéB𐅍CD")
"AéB𐅍CD"

julia> su[1]
'A'

julia> su[2]
'é'

julia> su[3]
ERROR: UnicodeError: invalid character index
in slow_utf8_next(::Array{UInt8,1}, ::UInt8, ::Int64) at ./strings/string.jl:67
in next at ./strings/string.jl:92 [inlined]
in getindex(::String, ::Int64) at ./strings/basic.jl:70

使用 lastindex(str) 而不是 length(str) 來查找字符串的長度:

julia> length(su)
6
julia> lastindex(su)
10

isascii() 函數用於測試字符串是 ASCII 還是包含 Unicode 字符:

julia> isascii(su)
false

在這個字符串中,「第二個」字符 (é) 有2個字節,「第四個」字符(𐅍)有4個字節。

對於處理這樣的字符串,有一些有用的函數,包括 thisind(), nextind()prevind():

for i in eachindex(su)
    println(thisind(su, i), " -> ", su[i])
end
1 -> A
2 -> é
4 -> B
5 -> 𐅍
9 -> C
10 -> D

「第三個」字符 B 從字符串中的第四個元素開始。

此外,可以使用 eachindex 迭代器:

for charindex in eachindex(su)
    @show su[charindex]
end
su[charindex] = 'A'
su[charindex] = 'é'
su[charindex] = 'B'
su[charindex] = '𐅍'
su[charindex] = 'C'
su[charindex] = 'D'

對字符串 split 和 join

[編輯]

您可以使用乘 (*) 運算符將字符串粘合在一起(通常稱為串聯的過程):

julia> "s" * "t"
"st"

如果您使用過其他程式語言,您可能希望使用加法(+)運算符:

julia> "s" + "t"
LoadError: MethodError: `+` has no method matching +(::String, ::String)

- 因此用 *.

如果你想把字符串『乘』起來,你也可以把它們提升為一個冪:

julia> "s" ^ 18
"ssssssssssssssssss"

你也可以用 string():

julia> string("s", "t")
"st"

但是,如果您想在循環中進行大量連接,也許最好使用字符串緩衝區方法(見下文)。


若要拆分字符串,請使用 split()函數。給出這個簡單的字符串:

julia> s = "You know my methods, Watson."
"You know my methods, Watson."

split() 函數的簡單調用在空格處分割字符串,返回一個分為五段的數組:

julia> split(s)
5-element Array{SubString{String},1}:
"You"
"know"
"my"
"methods,"
"Watson."

也可以指定要在以下位置拆分的 1個或多個字符的字符串:

julia> split(s, "e")
2-element Array{SubString{String},1}:
"You know my m"
"thods, Watson."

julia> split(s, " m")'
3-element Array{SubString{String},1}:
"You know"    
"y"       
"ethods, Watson."

用於分割的字符串不會顯示在最終結果中:

julia> split(s, "hod")
2-element Array{SubString{String},1}:
"You know my met"
"s, Watson."

如果要將字符串拆分為單獨的單字符串,請使用空字符串(「),它將字符串拆分為兩個字符:

julia> split(s,"")
28-element Array{SubString{String},1}:
"Y"
"o"
"u"
" "
"k"
"n"
"o"
"w"
" "
"m"
"y"
" "
"m"
"e"
"t"
"h"
"o"
"d"
"s"
","
" "
"W"
"a"
"t"
"s"
"o"
"n"
"."

也可以使用正則表達式來定義分割點來拆分字符串。使用特殊的正則表達式字符串結構 r" "。在其中,您可以使用具有特殊含義的正則表達式字符:

julia> split(s, r"a|e|i|o|u")
8-element Array{SubString{String},1}:
"Y"
""
" kn"
"w my m"
"th"
"ds, W"
"ts"
"n."

這裏,r"a|e|i|o|u" 是一個正則表達式字符串,而且-如果您喜歡正則表達式的話-它與任何元音都匹配。因此,結果數組由每個元音處的字符串分割組成。注意結果中的空字符串-如果您不想要這些字符串,請在末尾添加一個 false 標誌:

julia> split(s, r"a|e|i|o|u", false)
7-element Array{SubString{String},1}:
"Y"   
" kn"  
"w my m"
"th"  
"ds, W" 
"ts"  
"n."  

如果您想保留元音,而不是將它們用於拆分工作,則必須深入研究正則表達式文字字符串的世界。繼續讀下去。


可以使用 join() 連接以數組形式拆分字符串的元素:


julia> join(split(s, r"a|e|i|o|u", false), "aiou")
"Yaiou knaiouw my maiouthaiouds, Waioutsaioun."

Splitting using a function

[編輯]

Julia中的許多函數允許您使用函數作為函數調用的一部分。匿名函數很有用,因為您可以進行具有內置智能選擇的函數調用。例如,split() 允許您提供一個函數來代替分隔符字符。在下一個示例中,分隔符(奇怪地)指定為ASCII代碼為8的倍數的任何大寫字符:

julia> split(join(Char.(65:90)),  c -> Int(c) % 8 == 0)
4-element Array{SubString{String},1}:
 "ABCDEFG"
 "IJKLMNO"
 "QRSTUVW"
 "YZ"

字符對象

[編輯]

在上面,我們從較大的字符串中提取較小的字符串:

julia> s[1:1]
"a"

但當我們從字符串中提取單個元素時:

julia> s[1]
'a'

請注意單引號。在Julia中,這些字符用於標記字符對象,因此『a』是字符對象,而「a」是長度為1的字符串。他們是不相等的。

您可以輕鬆地將字符對象轉換為字符串:

julia> string('s') * string('d')
"sd"

或是

julia> string('s', 'd')
"sd"

使用 \U 轉義 輸入32位 Unicode 字符很容易(大寫表示32位)。小寫轉義序列 \u 可用於16位和8位字符:

julia> ('\U1014d', '\u2640', '\u26')
('𐅍','♀','&')

對於字符串,\Uxxxxxxx和\uxxxx語法更為嚴格。

julia> "\U0001014d2\U000026402\u26402\U000000a52\u00a52\U000000352\u00352\x352"
"𐅍2♀2♀2¥2¥2525252"

數字和字符串之間的轉換

[編輯]

將整數轉換為字符串也是 string() 函數的工作。關鍵字 base 用於指定轉換的數字基數,可用於將十進制數字轉換為二進制、八進制或十六進制字符串:

julia> string(11, base=2)
"1011"
julia> string(11, base=8)
"13"

julia> string(11, base=16)
"b"

julia> string(11)
"11"
julia> a = BigInt(2)^200
1606938044258990275541962092341162602522202993782792835301376
julia> string(a)
"1606938044258990275541962092341162602522202993782792835301376"
julia> string(a, base=16)
"1000000000000000000000000000000000000000000000000"

要將字符串轉換為數字,請使用 parse(),如果希望字符串被解釋為使用數字基數,則還可以指定數字基數(如二進制或十六進制):

julia> parse(Int, "100")
100

julia> parse(Int, "100", base=2)
4

julia> parse(Int, "100", base=16)
256

julia> parse(Float64, "100.32")
100.32

julia> parse(Complex{Float64}, "0 + 1im")
0.0 + 1.0im

字符與整數互相轉換

[編輯]

Int() 將字符轉換為整數,Char()將整數轉換為字符。

julia> Char(8253)
'‽': Unicode U+203d (category Po: Punctuation, other)

julia> Char(0x203d) # the Interrobang is Unicode U+203d in hexadecimal
'‽': Unicode U+203d (category Po: Punctuation, other)

julia> Int('‽')
8253

julia> string(Int('‽'), base=16)
"203d"

要從單個字符串轉換為代碼號(如其 ASCII 或 UTF code number),請嘗試以下操作:

julia> Int("S"[1])
83

printf 格式

[編輯]

如果您深深依賴於 C風格的 printf() 函數,那麼您能夠使用 Julia 宏(通過在宏前面加上 @ 符號來調用它們)。宏在 Printf 包中提供,您需要先加載該程序包:

julia> using Printf
julia> @printf("pi = %0.20f", float(pi))
pi = 3.14159265358979311600

或者,也可以使用 sprintf() 宏創建另一個字符串,也可以在 Printf 包中找到:

julia> @sprintf("pi = %0.20f", float(pi))
"pi = 3.14159265358979311600"

將字符串轉換為數組

[編輯]

要將字符串讀入數組,可以使用 IOBuffer() 函數。這在許多Julia函數(包括printf()中都是可用的。下面是一串數據(可能是從文件中讀取的):

data="1 2 3 4
5 6 7 8
9 0 1 2"

"1 2 3 4\n5 6 7 8\n9 0 1 2"

現在,您可以使用 readdlm()之類的函數「讀取」這個字符串,即「使用分隔符讀取(read with delimiters)」函數。這可以在DelimitedFiles包中找到。

julia> using DelimitedFiles
julia> readdlm(IOBuffer(data))
3x4 Array{Float64,2}:
1.0 2.0 3.0 4.0
5.0 6.0 7.0 8.0
9.0 0.0 1.0 2.0

您可以添加一個可選的類型限定:

julia> readdlm(IOBuffer(data), Int)
3x4 Array{Int64,2}:
1 2 3 4
5 6 7 8
9 0 1 2

有時,您希望對字符串執行一些操作,以便使用數組做得更好。這裏有一個例子。

julia> s = "/Users/me/Music/iTunes/iTunes Media/Mobile Applications";

可以使用 collect() 將路徑名字符串 分解 為字符對象數組,該方法將集合中的項或字符串分解為數組:

julia> collect(s)
55-element Array{Char,1}:
'/'
'U'
's'
'e'
'r'
's'
'/'
...

類似地,您可以使用split()拆分字符串並計算結果:

julia> split(s, "")
55-element Array{Char,1}:
'/'
'U'
's'
'e'
'r'
's'
'/'
...

要計算特定角色對象的出現次數,可以使用匿名函數:

julia> count(c -> c == '/', collect(s))
6

雖然在這裏轉換為數組是不必要和低效的。這裏有一個更好的方法:

julia> count(c -> c == '/', s)
6

查找和替換字符串中的內容

[編輯]

如果您想知道字符串是否包含特定字符,請使用通用的 in()函數。

julia> s = "Elementary, my dear Watson";
julia> in('m', s)
true

但是,接受兩個字符串的 occursin() 函數更有用,因為您可以將子串與一個或多個字符一起使用。請注意,將搜索詞放在第一位,然後是正在查找的字符串。occursin(needle, haystack)

julia> occursin("Wat", s)
true
julia> occursin("m", s)
true
julia> occursin("mi", s)
false
julia> occursin("me", s)
true

您可以使用 findfirst(needle, haystack) 獲取子字符串第一次出現的位置。第一個參數可以是單個字符、字符串或正則表達式:

julia> s ="You know my methods, Watson.";

julia> findfirst("meth", s)
13:16
julia> findfirst(r"[aeiou]", s)  # first vowel
2
julia> findfirst(isequal('a'), s) # first occurrence of character 'a'
23

在每種情況下,結果都包含字符的索引(如果存在)。

替換

[編輯]

replace()函數的作用是:返回一個新字符串,其中包含一個替換為其他字符的子字符串:

julia> replace("Sherlock Holmes", "e" => "ee")
"Sheerlock Holmees"

You use the => operator to specify the pattern you're looking for, and its replacement. Usually the third argument is another string, as here. But you can also supply a function that processes the result:

julia> replace("Sherlock Holmes", "e" => uppercase)
"ShErlock HolmEs"

where the function (here, the built-in uppercase() function) is applied to the matching substring.

There's no replace! function, where the "!" indicates a function that changes its argument. That's because you can't change a string — they're immutable.

Replacing using functions
[編輯]

Many functions in Julia allow you to supply functions as part of the function call, and you can make good use of anonymous functions for this. Here, for example, is how to use a function to provide random replacements in a replace() function.

julia>  t = "You can never foretell what any one man will do, but you can say with precision what an average number will be up to. Individuals vary, but percentages remain constant.";
julia> replace(t, r"a|e|i|o|u" => (c) -> rand(Bool) ? "0" : "1") 
"Y00 c1n n0v0r f1r0t1ll wh1t 0ny 0n0 m0n w1ll d0, b0t y01 c1n s1y w0th pr1c1s10n wh0t 1n 1v0r0g0 n1mb0r w0ll b0 0p t1. Ind1v0d11ls v0ry, b0t p1rc0nt0g0s r0m01n c1nst0nt."
julia> replace(t, r"a|e|i|o|u" => (c) -> rand(Bool) ? "0" : "1")
"Y11 c0n...n1v0r f0r1t0ll wh1t 1ny 0n1 m0n w1ll d1, b1t y10 c1n s1y w1th pr0c1s01n wh0t 0n 0v1r0g0 n1mb1r w0ll b0 1p t1. Ind1v0d01ls v0ry, b1t p0rc1nt1g0s r0m01n c1nst0nt."

正則表達式

[編輯]

You can use regular expressions to find matches for substrings. Some functions that accept a regular expression are:

  • replace() changes occurrences of regular expressions
  • match() returns the first match or nothing
  • eachmatch() returns an iterator that lets you search through all matches
  • split() splits a string at every match

Use replace() to replace each consonant with an underscore:

julia> replace("Elementary, my dear Watson!", r"[^aeiou]" => "_")
"__e_e__a________ea___a__o__"

and the following code replaces each vowel with the results of running a function on each match:

julia> replace("Elementary, my dear Watson!", r"[aeiou]" => uppercase)
"ElEmEntAry, my dEAr WAtsOn!"

With replace() you can access the matches if you provide a special substitution string s"", where \1 refers to the first match, \2 to the second, and so on. With this regex operation, each lowercase letter preceded by a space is repeated three times:

julia> replace("Elementary, my dear Watson!", r"(\s)([a-z])" => s"\1\2\2\2")
"Elementary, mmmy dddear Watson!"

For more regular expression fun, there are the -match- functions.

Here I've loaded the complete text of "The Adventures of Sherlock Holmes" from a file into the string called text:

julia> f = "/tmp/adventures-of-sherlock-holmes.txt"
julia> text = read(f, String);

To use the possibility of a match as a Boolean condition, suitable for use in an if statement for example, use occursin().

julia> occursin(r"Opium", text)
false

That's odd. We were expecting to find evidence of the great detective's peculiar pharmacological recreations. In fact, the word "opium" does appear in the text, but only in lower-case, hence this false result—regular expressions are case-sensitive.

julia> occursin(r"(?i)Opium", text)
true

This is a case-insensitive search, set by the flag (?i)), and it returns true.

You could check every line for the word using a simple loop:

for l in split(text, "\n")
    occursin(r"opium", l) && println(l)
end
opium. The habit grew upon him, as I understand, from some
he had, when the fit was on him, made use of an opium den in the
brown opium smoke, and terraced with wooden berths, like the
wrinkled, bent with age, an opium pipe dangling down from between
very short time a decrepit figure had emerged from the opium den,
opium-smoking to cocaine injections, and all the other little
steps - for the house was none other than the opium den in which
lives upon the second floor of the opium den, and who was
learn to have been the lodger at the opium den, and to have been
doing in the opium den, what happened to him when there, where is
"Had he ever showed any signs of having taken opium?"
room above the opium den when I looked out of my window and saw,

For more useable output (in the REPL), add enumerate() and some highlighting:

red = Base.text_colors[:red]; default = Base.text_colors[:default];
for (n, l) in enumerate(split(text, "\n"))
    occursin(r"opium", l) && println("$n $(replace(l, "opium" => "$(red)opium$(default)"))")
end
5087 opium. The habit grew upon him, as I understand, from some
5140 he had, when the fit was on him, made use of an opium den in the
5173 brown opium smoke, and terraced with wooden berths, like the
5237 wrinkled, bent with age, an opium pipe dangling down from between
5273 very short time a decrepit figure had emerged from the opium den,
5280 opium-smoking to cocaine injections, and all the other little
5429 steps - for the house was none other than the opium den in which
5486 lives upon the second floor of the opium den, and who was
5510 learn to have been the lodger at the opium den, and to have been
5593 doing in the opium den, what happened to him when there, where is
5846 "Had he ever showed any signs of having taken opium?"
6129 room above the opium den when I looked out of my window and saw,

There's an alternative syntax for adding regex modifiers, such as case-insensitive matches. Notice the "i" immediately following the regex string in the second example:

julia> occursin(r"Opium", text)
false

julia> occursin(r"Opium"i, text)
true

With the eachmatch() function, you apply the regex to the string to produce an iterator. For example, to look for substrings in our text matching the letters "L", followed by some other characters, ending with "ed":

julia> lmatch = eachmatch(r"L.*?ed", text)

The result in lmatch is an iterable object containing all the matches, as RegexMatch objects:

julia> collect(lmatch)[1:10]
10-element Array{RegexMatch,1}:
RegexMatch("London, and proceed")         
RegexMatch("London is a pleasant thing indeed")  
RegexMatch("Looking for lodgings,\" I answered") 
RegexMatch("London he had received")       
RegexMatch("Lied")                
RegexMatch("Life,\" and it attempted")      
RegexMatch("Lauriston Gardens wore an ill-omened")
RegexMatch("Let\" card had developed")      
RegexMatch("Lestrade, is here. I had relied")   
RegexMatch("Lestrade grabbed")         

We can step through the iterator and look at each match in turn. You can access a number of fields of a RegexMatch, to extract information about the match. These include captures, match, offset, offsets, and regex. For example, the match field contains the matched substring:

for i in lmatch
    println(i.match)
end
London - quite so! Your Majesty, as I understand, became entangled
Lodge. As it pulled
Lord, Mr. Wilson, that I was a red
League of the Red
League was founded
London when he was young, and he wanted
LSON" in white letters, upon a corner house, announced
League, and the copying of the 'Encyclopaed
Leadenhall Street Post Office, to be left till called
Let the whole incident be a sealed
Lestrade, being rather puzzled
Lestrade would have noted
...
Lestrade," drawled
Lestrade looked
Lord St. Simon has not already arrived
Lord St. Simon sank into a chair and passed
Lord St. Simon had by no means relaxed
Lordship. "I may be forced
London. What could have happened
London, and I had placed

Other fields include captures, the captured substrings as an array of strings, offset, the offset into the string at which the whole match begins, and offsets, the offsets of the captured substrings.

To get an array of matching strings, use something like this:

julia> collect(m.match for m in eachmatch(r"L.*?ed", text))
58-element Array{SubString{String},1}:
"London - quite so! Your Majesty, as I understand, became entangled"
"Lodge. As it pulled"                        
"Lord, Mr. Wilson, that I was a red"                
"League of the Red"                         
"League was founded"                        
"London when he was young, and he wanted"              
"Leadenhall Street Post Office, to be left till called"       
"Let the whole incident be a sealed"                
"Lestrade, being rather puzzled"                  
"Lestrade would have noted"                     
"Lestrade looked"                          
"Lestrade laughed"                         
"Lestrade shrugged"                         
"Lestrade called"                          
... 
"Lord St. Simon shrugged"                      
"Lady St. Simon was decoyed"                    
"Lestrade,\" drawled"                        
"Lestrade looked"                          
"Lord St. Simon has not already arrived"              
"Lord St. Simon sank into a chair and passed"            
"Lord St. Simon had by no means relaxed"              
"Lordship. \"I may be forced"                    
"London. What could have happened"                 
"London, and I had placed" 

The basic match() function looks for the first match for your regex. Use the match field to extract the information from the RegexMatch object:

julia> match(r"She.*",text).match
"Sherlock Holmes she is always THE woman. I have seldom heard\r"

A more streamlined way of obtaining matching lines from a file is this:

julia> f = "adventures of sherlock holmes.txt"

julia> filter(s -> occursin(r"(?i)Opium", s), map(chomp, readlines(open(f))))
12-element Array{SubString{String},1}:
"opium. The habit grew upon him, as I understand, from some"    
"he had, when the fit was on him, made use of an opium den in the" 
"brown opium smoke, and terraced with wooden berths, like the"   
"wrinkled, bent with age, an opium pipe dangling down from between"
"very short time a decrepit figure had emerged from the opium den,"
"opium-smoking to cocaine injections, and all the other little"  
"steps - for the house was none other than the opium den in which" 
"lives upon the second floor of the opium den, and who was"    
"learn to have been the lodger at the opium den, and to have been" 
"doing in the opium den, what happened to him when there, where is"
"\"Had he ever showed any signs of having taken opium?\""     
"room above the opium den when I looked out of my window and saw,"

Making a Regex

[編輯]

Sometimes you want to make a regular expression from within your code. You can do this by making a Regex object. Here is one way you could count the number of vowels in the text:

f = open("sherlock-holmes.txt")

text = read(f, String)

for vowel in "aeiou"
    r = Regex(string(vowel))
    l = [m.match for m = eachmatch(r, thetext)]
    println("there are $(length(l)) letter \"$vowel\"s in the text.")
end
there are 219626 letter "a"s in the text.
there are 337212 letter "e"s in the text.
there are 167552 letter "i"s in the text.
there are 212834 letter "o"s in the text.
there are 82924 letter "u"s in the text.

判斷和更改字符串

[編輯]

There are lots of functions for testing and changing strings:

  • length(str) length of string
  • sizeof(str) length/size
  • startswith(strA, strB) does strA start with strB?
  • endswith(strA, strB) does strA end with strB?
  • occursin(strA, strB) does strA occur in strB?
  • all(isletter, str) is str entirely letters?
  • all(isnumeric, str) is str entirely number characters?
  • isascii(str) is str ASCII?
  • all(iscntrl, str) is str entirely control characters?
  • all(isdigit, str) is str 0-9?
  • all(ispunct, str) does str consist of punctuation?
  • all(isspace, str) is str whitespace characters?
  • all(isuppercase, str) is str uppercase?
  • all(islowercase, str) is str entirely lowercase?
  • all(isxdigit, str) is str entirely hexadecimal digits?
  • uppercase(str) return a copy of str converted to uppercase
  • lowercase(str) return a copy of str converted to lowercase
  • titlecase(str) return copy of str with the first character of each word converted to uppercase
  • uppercasefirst(str) return copy of str with first character converted to uppercase
  • lowercasefirst(str) return copy of str with first character converted to lowercase
  • chop(str) return a copy with the last character removed
  • chomp(str) return a copy with the last character removed only if it's a newline

Streams

[編輯]

To write to a string, you can use a Julia stream. The sprint() (String Print) function lets you use a function as the first argument, and uses the function and the rest of the arguments to send information to a stream, returning the result as a string.

For example, consider the following function, f. The body of the function maps an anonymous 'print' function over the arguments, enclosing them with angle brackets. When used by sprint, the function f processes the remaining arguments and sends them to the stream.

function f(io::IO, args...)
    map((a) -> print(io,"<",a, ">"), args)
end
f (generic function with 1 method)
julia> sprint(f, "fred", "jim", "bill", "fred blogs")
"<fred><jim><bill><fred blogs>"

Functions like println() can take an IOBuffer or stream as their first argument. This lets you print to streams instead of printing to the standard output device:

julia> iobuffer = IOBuffer()
IOBuffer(data=Uint8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1)
julia> for i in 1:100
           println(iobuffer, string(i))
       end

After this, the in-memory stream called iobuffer is full of numbers and newlines, even though nothing was printed on the terminal. To copy the contents of iobuffer from the stream to a string or array, you can use take!():

julia> String(take!(iobuffer))
"1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14 ... \n98\n99\n100\n"
« Introducing Julia
Strings and characters
»
Dictionaries and sets Working with text files