Julia(字符串)

2021-04-14 12:51:53 浏览数 (1)

字符串是字符的有限序列。当然,真正的麻烦来自于人们问一个角色是什么。英语演讲熟悉的字符是字母ABC等,用数字和常用标点符号在一起。这些字符通过ASCII标准进行了标准化,并映射到0到127之间的整数值。当然,还有许多其他非英语语言使用的字符,包括带有重音和其他修饰的ASCII字符变体,相关的脚本(例如西里尔字母和希腊语)以及与ASCII和英语完全无关的脚本,包括阿拉伯语,中文,希伯来语,北印度语,日语和韩语。该统一标准解决了一个字符的复杂性,通常被认为是解决该问题的权威标准。根据您的需要,您可以完全忽略这些复杂性,而假装仅存在ASCII字符,或者可以编写可以处理任何字符或处理非ASCII文本时可能遇到的编码的代码。Julia使处理普通ASCII文本简单而有效,而处理Unicode则尽可能简单而高效。特别是,您可以编写C样式的字符串代码来处理ASCII字符串,并且它们在性能和语义方面都将按预期工作。如果此类代码遇到非ASCII文本,它将以明确的错误消息正常地失败,而不是默默地引入损坏的结果。当这个情况发生时,

有关Julia的字符串,有一些值得注意的高级功能:

  • Julia中用于字符串(和字符串文字)的内置具体类型为String。这通过UTF-8编码支持所有Unicode字符。(提供了与其他Unicode编码之间进行转换的功能。)transcode()
  • 所有字符串类型都是抽象类型的子类型AbstractString,外部包定义了其他AbstractString子类型(例如,用于其他编码)。如果定义的函数需要字符串参数,则应将类型声明为AbstractString,以便接受任何字符串类型。
  • 像C和Java一样,但与大多数动态语言不同,Julia具有代表一个字符的一流类型,称为Char。这只是一种特殊的32位原始类型,其数字值表示Unicode代码点。
  • 与Java中一样,字符串是不可变的:AbstractString对象的值无法更改。要构造一个不同的字符串值,请从其他字符串的一部分构造一个新的字符串。
  • 从概念上讲,字符串是从索引到字符的部分函数:对于某些索引值,不返回任何字符值,而是引发异常。这允许通过编码表示形式的字节索引而不是字符索引有效地索引字符串,而这对于Unicode字符串的可变宽度编码既不能有效实现,也不能简单地实现。

性格

Char值代表单个字符:它仅仅是一个32位的原始类型用特殊文字表示和适当的算术行为,其数值被解释为Unicode代码点。下面是Char值输入并显示:

代码语言:javascript复制
julia> 'x'
'x': ASCII/Unicode U 0078 (category Ll: Letter, lowercase)

julia> typeof(ans)
Char

您可以Char轻松地将a转换为其整数值,即代码点:

代码语言:javascript复制
julia> Int('x')
120

julia> typeof(ans)
Int64

在32位架构上,typeof(ans)将为Int32。您可以Char轻松地将整数值转换回a :

代码语言:javascript复制
julia> Char(120)
'x': ASCII/Unicode U 0078 (category Ll: Letter, lowercase)

并非所有整数值都是有效的Unicode代码点,但是为了提高性能,Char()转换并不会检查每个字符值是否有效。如果要检查每个转换后的值是否是有效的代码点,请使用以下isvalid()函数:

代码语言:javascript复制
julia> Char(0x110000)
'U110000': Unicode U 110000 (category Cn: Other, not assigned)

julia> isvalid(Char, 0x110000)
false

截至发稿时,有效的Unicode代码点是U 00通过U d7ffU e000通过U 10ffff。这些还没有全部被赋予可理解的含义,也没有必要由应用程序解释,但是所有这些值都被认为是有效的Unicode字符。

您可以使用单引号将任何Unicode字符输入u,最多使用四个十六进制数字或U最多八个十六进制数字(最长有效值仅需要六个):

代码语言:javascript复制
julia> 'u0'
'': ASCII/Unicode U 0000 (category Cc: Other, control)

julia> 'u78'
'x': ASCII/Unicode U 0078 (category Ll: Letter, lowercase)

julia> 'u2200'
'∀': Unicode U 2200 (category Sm: Symbol, math)

julia> 'U10ffff'
'U10ffff': Unicode U 10ffff (category Cn: Other, not assigned)

Julia使用系统的语言环境和语言设置来确定哪些字符可以原样打印,哪些字符必须使用常规,转义uU输入形式输出。除了这些Unicode转义形式之外,还可以使用C的所有传统转义输入形式:

代码语言:javascript复制
julia> Int('')
0

julia> Int('t')
9

julia> Int('n')
10

julia> Int('e')
27

julia> Int('x7f')
127

julia> Int('177')
127

julia> Int('xff')
255

您可以使用Char值进行比较和有限的算术运算:

代码语言:javascript复制
julia> 'A' < 'a'
true

julia> 'A' <= 'a' <= 'Z'
false

julia> 'A' <= 'X' <= 'Z'
true

julia> 'x' - 'a'
23

julia> 'A'   1
'B': ASCII/Unicode U 0042 (category Lu: Letter, uppercase)

字符串基础

字符串文字用双引号或三重双引号分隔:

代码语言:javascript复制
julia> str = "Hello, world.n"
"Hello, world.n"

julia> """Contains "quote" characters"""
"Contains "quote" characters"

如果要从字符串中提取字符,请对其进行索引:

代码语言:javascript复制
julia> str[1]
'H': ASCII/Unicode U 0048 (category Lu: Letter, uppercase)

julia> str[6]
',': ASCII/Unicode U 002c (category Po: Punctuation, other)

julia> str[end]
'n': ASCII/Unicode U 000a (category Cc: Other, control)

Julia中的所有索引都是基于1的:任何整数索引对象的第一个元素都位于索引1处。(如下所示,这不一定意味着最后一个元素位于index处n,其中n的长度是字符串。)

在任何索引表达式中,关键字end都可以用作最后一个索引的缩写(由计算endof(str))。您可以使用进行算术运算和其他运算end,就像正常值一样:

代码语言:javascript复制
julia> str[end-1]
'.': ASCII/Unicode U 002e (category Po: Punctuation, other)

julia> str[end÷2]
' ': ASCII/Unicode U 0020 (category Zs: Separator, space)

使用小于1或大于的索引end会引发错误:

代码语言:javascript复制
julia> str[0]
ERROR: BoundsError: attempt to access "Hello, world.n"
  at index [0]
[...]

julia> str[end 1]
ERROR: BoundsError: attempt to access "Hello, world.n"
  at index [15]
[...]

您还可以使用范围索引提取子字符串:

代码语言:javascript复制
julia> str[4:9]
"lo, wo"

请注意,表达式str[k]str[k:k]不会给出相同的结果:

代码语言:javascript复制
julia> str[6]
',': ASCII/Unicode U 002c (category Po: Punctuation, other)

julia> str[6:6]
","

前者是type的单个字符值Char,而后者是恰好只包含一个字符的字符串值。在朱莉娅,这些是完全不同的事情。

Unicode和UTF-8

Julia完全支持Unicode字符和字符串。正如上面所讨论的,在字符文字,Unicode代码点可以使用Unicode表示uU转义序列,以及所有的标准C转义序列。这些同样可以用来编写字符串文字:

代码语言:javascript复制
julia> s = "u2200 x u2203 y"
"∀ x ∃ y"

这些Unicode字符显示为转义符还是显示为特殊字符取决于终端的语言环境设置及其对Unicode的支持。字符串文字使用UTF-8编码进行编码。UTF-8是宽度可变的编码,这意味着并非所有字符都以相同的字节数进行编码。在UTF-8中,ASCII字符(即代码点小于0x80(128)的字符)使用ASCII编码,使用单个字节,而0x80及更高版本的代码点则使用多个字节编码-每个字符最多四个。这意味着并非UTF-8字符串中的每个字节索引都必须是字符的有效索引。如果在这样的无效字节索引处索引到字符串,则会引发错误:

代码语言:javascript复制
julia> s[1]
'∀': Unicode U 2200 (category Sm: Symbol, math)

julia> s[2]
ERROR: UnicodeError: invalid character index
[...]

julia> s[3]
ERROR: UnicodeError: invalid character index
[...]

julia> s[4]
' ': ASCII/Unicode U 0020 (category Zs: Separator, space)

在这种情况下,该字符是一个三字节字符,因此索引2和3无效,下一个字符的索引为4;可以通过计算下一个有效索引nextind(s,1),然后通过来计算下一个索引nextind(s,4),依此类推。

由于采用可变长度编码,字符串(由给出length(s))中的字符数并不总是与最后一个索引相同。如果遍历索引1至endof(s)索引到s,则不会引发错误的返回字符序列是组成字符串的字符序列s。因此,我们具有标识length(s) <= endof(s),因为字符串中的每个字符都必须具有自己的索引。以下是遍历以下字符的效率低下且冗长的方法s

代码语言:javascript复制
julia> for i = 1:endof(s)
           try
               println(s[i])
           catch
               # ignore the index error
           end
       end
∀

x

∃

y

空行上实际上有空格。幸运的是,上面的惯用语对于迭代字符串中的字符是不必要的,因为您可以将字符串用作可迭代对象,而无需异常处理:

代码语言:javascript复制
julia> for c in s
           println(c)
       end
∀

x

∃

y

Julia默认使用UTF-8编码,并且可以通过软件包添加对新编码的支持。例如,LegacyStrings.jl包实现UTF16StringUTF32String类型。目前,关于其他编码以及如何实现对它们的支持的其他讨论不在本文的讨论范围之内。有关UTF-8编码问题的进一步讨论,请参见下面有关字节数组文字的部分。transcode()提供该功能是为了在各种UTF-xx编码之间转换数据,主要是为了处理外部数据和库。

级联

串联是最常见和有用的字符串操作之一:

代码语言:javascript复制
julia> greet = "Hello"
"Hello"

julia> whom = "world"
"world"

julia> string(greet, ", ", whom, ".n")
"Hello, world.n"

Julia还提供*了字符串连接:

代码语言:javascript复制
julia> greet * ", " * whom * ".n"
"Hello, world.n"

虽然*可能看起来像一个奇怪的选择,其提供语言的用户 字符串连接,这使用*在数学的先例,特别是在抽象代数。

在数学中, 通常表示可交换运算,其中操作数的顺序无关紧要。这样的一个例子是矩阵加法,其中A B == B A对于任何矩阵AB具有相同的形状。相反,*通常表示非交换操作,其中操作数的顺序确实很重要。这样的一个例子是矩阵乘法,通常是A * B != B * A。与矩阵乘法一样,字符串串联也是不可交换的:greet * whom != whom * greet。因此,*对于固定字符串连接运算符,这是更自然的选择,与常见的数学用法一致。

更确切地说,所有有限长度的字符串S的集合与字符串串联运算符一起*形成一个自由的单面体(S*)。此集合的标识元素是空字符串""。每当一个自由幺是不可交换的,则操作通常被表示为cdot*或类似的符号,而不是 ,这如所述通常意味着交换性。

插补

但是,使用串联构造字符串可能会变得有些麻烦。为了减少对这些冗长的调用string()或重复乘法的需求,Julia允许使用$,在Perl中内插到字符串文字中,如Perl中所示:

代码语言:javascript复制
julia> "$greet, $whom.n"
"Hello, world.n"

这更易读和方便,并且等效于上述字符串连接-系统将这个明显的单个字符串文字重写为带变量的字符串文字的串联。

后面最短的完整表达式$作为其值要插入到字符串中的表达式。因此,您可以使用括号将任何表达式插入到字符串中:

代码语言:javascript复制
julia> "1   2 = $(1   2)"
"1   2 = 3"

串联和字符串插值都string()需要将对象转换为字符串形式。大多数非AbstractString对象都将转换为与它们作为文字表达式输入方式非常接近的字符串:

代码语言:javascript复制
julia> v = [1,2,3]
3-element Array{Int64,1}:
 1
 2
 3

julia> "v: $v"
"v: [1, 2, 3]"

string()是身份AbstractStringChar价值,所以这些插值到字符串作为自己的,不带引号和转义:

代码语言:javascript复制
julia> c = 'x'
'x': ASCII/Unicode U 0078 (category Ll: Letter, lowercase)

julia> "hi, $c"
"hi, x"

要将文字包含$在字符串文字中,请使用反斜杠对其进行转义:

代码语言:javascript复制
julia> print("I have $100 in my account.n")
I have $100 in my account.

三重引用的字符串文字

使用三引号("""...""")创建字符串时,它们具有一些特殊的行为,这些行为对于创建更长的文本块很有用。首先,如果开头"""后面有换行符,则从结果字符串中删除换行符。

代码语言:javascript复制
"""hello"""

相当于

代码语言:javascript复制
"""
hello"""

代码语言:javascript复制
"""

hello"""

开头将包含文字换行符。尾随空格保持不变。它们可以包含"符号而不能转义。三引号的字符串也被缩进最小缩进行的水平。这对于在缩进的代码中定义字符串很有用。例如:

代码语言:javascript复制
julia> str = """
           Hello,
           world.
         """
"  Hello,n  world.n"

在这种情况下,关闭之前的最后(空)行将"""设置缩进级别。

请注意n,即使编辑器r对末尾使用回车符(CR)或CRLF组合,文字字符串的换行符(无论是单引号还是三引号)都会在字符串中产生换行符(LF)。要在字符串中包含CR,请使用显式转义r; 例如,您可以输入文字字符串"a CRLF line endingrn"

常用操作

您可以使用标准比较运算符按字典顺序比较字符串:

代码语言:javascript复制
julia> "abracadabra" < "xylophone"
true

julia> "abracadabra" == "xylophone"
false

julia> "Hello, world." != "Goodbye, world."
true

julia> "1   2 = 3" == "1   2 = $(1   2)"
true

您可以使用以下search()功能搜索特定字符的索引:

代码语言:javascript复制
julia> search("xylophone", 'x')
1

julia> search("xylophone", 'p')
5

julia> search("xylophone", 'z')
0

您可以通过提供第三个参数来开始搜索给定偏移量的字符:

代码语言:javascript复制
julia> search("xylophone", 'o')
4

julia> search("xylophone", 'o', 5)
7

julia> search("xylophone", 'o', 8)
0

您可以使用该contains()函数检查字符串中是否包含子字符串:

代码语言:javascript复制
julia> contains("Hello, world.", "world")
true

julia> contains("Xylophon", "o")
true

julia> contains("Xylophon", "a")
false

julia> contains("Xylophon", 'o')
ERROR: MethodError: no method matching contains(::String, ::Char)
Closest candidates are:
  contains(!Matched::Function, ::Any, !Matched::Any) at reduce.jl:664
  contains(::AbstractString, !Matched::AbstractString) at strings/search.jl:378

最后一个错误是因为'o'是字符文字,并且contains()是寻找子序列的通用函数。要在序列中查找元素,必须使用in()

另外两个方便的字符串函数是repeat()join()

代码语言:javascript复制
julia> repeat(".:Z:.", 10)
".:Z:..:Z:..:Z:..:Z:..:Z:..:Z:..:Z:..:Z:..:Z:..:Z:."

julia> join(["apples", "bananas", "pineapples"], ", ", " and ")
"apples, bananas and pineapples"

其他一些有用的功能包括:

  • endof(str)给出可用于索引的最大(字节)索引str
  • length(str)中的字符数str
  • i = start(str)给出可以在其中找到字符的第一个有效索引str(通常为1)。
  • c, j = next(str,i)在索引处或索引之后返回下一个字符,i并在其后返回下一个有效字符索引。使用start()和时endof(),可用于迭代中的字符str
  • ind2chr(str,i)给出str最多且包括at索引处的字符数i
  • chr2ind(str,j)给出j第一个字符str出现的索引。

非标准字符串文字

在某些情况下,您想构造一个字符串或使用字符串语义,但是标准字符串构造的行为并不是所需要的。对于此类情况,Julia提供了非标准的字符串文字。非标准字符串文字看起来像常规的双引号字符串文字,但会立即加上一个标识符作为前缀,并且行为与普通的字符串文字并不完全相同。如下所述,正则表达式,字节数组文字和版本号文字是非标准字符串文字的一些示例。元编程部分中提供了其他示例。

常用表达

Julia具有PCRE库提供的与Perl兼容的正则表达式(regexes)。正则表达式通过两种方式与字符串相关:明显的联系是,正则表达式用于查找字符串中的正则模式。另一个联系是,正则表达式本身是作为字符串输入的,它们被解析为状态机,可用于有效地搜索字符串中的模式。在Julia中,正则表达式使用以非标准字符串文字作为前缀的前缀,这些文字以各种标识符开头r。没有打开任何选项的最基本的正则表达式文字只使用r"..."

代码语言:javascript复制
julia> r"^s*(?:#|$)"
r"^s*(?:#|$)"

julia> typeof(ans)
Regex

要检查正则表达式是否与字符串匹配,请使用ismatch()

代码语言:javascript复制
julia> ismatch(r"^s*(?:#|$)", "not a comment")
false

julia> ismatch(r"^s*(?:#|$)", "# a comment")
true

从这里可以看到,ismatch()仅返回true或false,指示给定的正则表达式是否与字符串匹配。但是,通常,人们不仅想知道字符串是否匹配,还想知道如何匹配。要捕获有关匹配的信息,请改用match()函数:

代码语言:javascript复制
julia> match(r"^s*(?:#|$)", "not a comment")

julia> match(r"^s*(?:#|$)", "# a comment")
RegexMatch("#")

如果正则表达式与给定的字符串不匹配,则match()返回nothing–一个特殊值,该值不会在交互式提示符下显示任何内容。除了不打印以外,它是一个完全正常的值,您可以通过编程方式对其进行测试:

代码语言:javascript复制
m = match(r"^s*(?:#|$)", line)
if m === nothing
    println("not a comment")
else
    println("blank or comment")
end

如果正则表达式匹配,则返回的值match()是一个RegexMatch对象。这些对象记录表达式的匹配方式,包括模式匹配的子字符串和任何捕获的子字符串(如果有)。此示例仅捕获匹配的子字符串部分,但是也许我们希望捕获注释字符之后的所有非空白文本。我们可以执行以下操作:

代码语言:javascript复制
julia> m = match(r"^s*(?:#s*(.*?)s*$|$)", "# a comment ")
RegexMatch("# a comment ", 1="a comment")

调用时match(),您可以选择指定一个索引以开始搜索。例如:

代码语言:javascript复制
julia> m = match(r"[0-9]","aaaa1aaaa2aaaa3",1)
RegexMatch("1")

julia> m = match(r"[0-9]","aaaa1aaaa2aaaa3",6)
RegexMatch("2")

julia> m = match(r"[0-9]","aaaa1aaaa2aaaa3",11)
RegexMatch("3")

您可以从RegexMatch对象中提取以下信息:

  • 整个子字符串匹配: m.match
  • 捕获的子字符串为字符串数组: m.captures
  • 整个比赛开始的偏移量: m.offset
  • 捕获的子字符串的偏移量作为矢量: m.offsets

当捕获不匹配时,该位置将m.captures包含一个子字符串,而不是一个子字符串,nothing并且m.offsets其偏移量为零(请注意,Julia中的索引是从1开始的,因此字符串的零偏移量是无效的)。这是一些人为的示例:

代码语言:javascript复制
julia> m = match(r"(a|b)(c)?(d)", "acd")
RegexMatch("acd", 1="a", 2="c", 3="d")

julia> m.match
"acd"

julia> m.captures
3-element Array{Union{SubString{String}, Void},1}:
 "a"
 "c"
 "d"

julia> m.offset
1

julia> m.offsets
3-element Array{Int64,1}:
 1
 2
 3

julia> m = match(r"(a|b)(c)?(d)", "ad")
RegexMatch("ad", 1="a", 2=nothing, 3="d")

julia> m.match
"ad"

julia> m.captures
3-element Array{Union{SubString{String}, Void},1}:
 "a"
 nothing
 "d"

julia> m.offset
1

julia> m.offsets
3-element Array{Int64,1}:
 1
 0
 2

将捕获作为数组返回是很方便的,这样就可以使用解构语法将它们绑定到局部变量:

代码语言:javascript复制
julia> first, second, third = m.captures; first
"a"

也可以通过RegexMatch使用捕获组的编号或名称为对象建立索引来访问捕获:

代码语言:javascript复制
julia> m=match(r"(?<hour>d ):(?<minute>d )","12:45")
RegexMatch("12:45", hour="12", minute="45")

julia> m[:minute]
"45"

julia> m[2]
"45"

使用时,可以replace()通过使用n引用第n个捕获组并在替换字符串前添加前缀来在替换字符串中引用捕获s。捕获组0引用整个匹配对象。命名的捕获组可以用代替引用g<groupname>。例如:

代码语言:javascript复制
julia> replace("first second", r"(w ) (?<agroup>w )", s"g<agroup> 1")
"second first"

编号捕获组也可以作为g<n>歧义引用,例如:

代码语言:javascript复制
julia> replace("a", r".", s"g<0>1")
"a1"

您可以通过标志的某种组合修改正则表达式的行为ims,和x后右双引号。这些标志的含义与在Perl中的含义相同,如以下摘自perlre联机帮助页中所述:

代码语言:javascript复制
i   Do case-insensitive pattern matching.

    If locale matching rules are in effect, the case map is taken
    from the current locale for code points less than 255, and
    from Unicode rules for larger code points. However, matches
    that would cross the Unicode rules/non-Unicode rules boundary
    (ords 255/256) will not succeed.

m   Treat string as multiple lines.  That is, change "^" and "$"
    from matching the start or end of the string to matching the
    start or end of any line anywhere within the string.

s   Treat string as single line.  That is, change "." to match any
    character whatsoever, even a newline, which normally it would
    not match.

    Used together, as r""ms, they let the "." match any character
    whatsoever, while still allowing "^" and "$" to match,
    respectively, just after and just before newlines within the
    string.

x   Tells the regular expression parser to ignore most whitespace
    that is neither backslashed nor within a character class. You
    can use this to break up your regular expression into
    (slightly) more readable parts. The '#' character is also
    treated as a metacharacter introducing a comment, just as in
    ordinary code.

例如,以下正则表达式将所有三个标志都打开:

代码语言:javascript复制
julia> r"a .*b .*?d$"ism
r"a .*b .*?d$"ims

julia> match(r"a .*b .*?d$"ism, "Goodbye,nOh, angry,nBad worldn")
RegexMatch("angry,nBad world")

r"""..."""还支持形式为三引号的正则表达式字符串(对于包含引号或换行符的正则表达式,可能会很方便)。

字节数组文字

另一个有用的非标准字符串文字是字节数组字符串文字:b"..."。这种形式使您可以使用字符串表示法来表示文字字节数组,即UInt8值数组。字节数组文字的规则如下:

  • ASCII字符和ASCII转义产生单个字节。
  • x八进制转义序列产生对应于转义值的字节
  • Unicode转义序列产生一个字节编码序列,该字节序列以UTF-8编码。

这些规则之间存在一些重叠,因为x前两个规则都覆盖了小于0x80(128)的八进制转义和八进制转义的行为,但是此处这些规则是一致的。这些规则一起使人们可以轻松地使用ASCII字符,任意字节值和UTF-8序列来生成字节数组。这是使用这三个示例的示例:

代码语言:javascript复制
julia> b"DATAxffu2200"
8-element Array{UInt8,1}:
 0x44
 0x41
 0x54
 0x41
 0xff
 0xe2
 0x88
 0x80

ASCII字符串“ DATA”对应于字节68、65、84、65。xff产生单个字节255。Unicode转义u2200以UTF-8编码为三个字节226、136、128。请注意,结果字节数组确实与有效的UTF-8字符串不对应–如果尝试将其用作常规字符串文字,则会出现语法错误:

代码语言:javascript复制
julia> "DATAxffu2200"
ERROR: syntax: invalid UTF-8 sequence

还要注意xff和之间的显着区别uff:前一个转义序列编码字节255,而后一个转义序列表示代码点255,在UTF-8中将其编码为两个字节:

代码语言:javascript复制
julia> b"xff"
1-element Array{UInt8,1}:
 0xff

julia> b"uff"
2-element Array{UInt8,1}:
 0xc3
 0xbf

在字符文字中,此区别被掩盖了,xff并允许代表代码点255,因为字符始终代表代码点。字符串,但是,x转义始终代表字节,而不是码点,而uU逸出始终表示代码点,其在一个或多个字节编码。对于小于的代码点u80,碰巧每个代码点的UTF-8编码只是由相应的x转义符产生的单个字节,因此可以安全地忽略此区别。对于逃逸x80通过xff相比,u80通过uff但是,有一个主要区别:前者转义所有编码的单个字节,除非后面有非常特定的连续字节,否则它们不构成有效的UTF-8数据,而后者转义全部表示具有两字节编码的Unicode代码点。

如果这一切都非常令人困惑,请尝试阅读“绝对绝对肯定地每个软件开发人员都必须了解的Unicode和字符集”。这是对Unicode和UTF-8的出色介绍,并可能有助于减轻对此问题的某些困惑。

版本号文字

版本号可以很容易地用形式非标准的字符串文字表示v"..."。版本号文字创建的VersionNumber对象遵循语义版本控制的规范,因此由主要,次要和补丁数字值组成,然后由预发行版本和构建字母数字注释组成。例如,v"0.2.1-rc1 win64"分为主要版本0,次要版本2,补丁版本1,预发行版本rc1和内部版本win64。输入版本文字时,除主版本号外的所有内容都是可选的,因此,例如 v"0.2",等价于v"0.2.0"(带有空的预发行/构建注释),v"2"等价于v"2.0.0",等等。

VersionNumber对象最有助于轻松,正确地比较两个(或多个)版本。例如,该常数VERSION将Julia版本号作为一个VersionNumber对象,因此可以使用以下简单语句来定义一些特定于版本的行为:

代码语言:javascript复制
if v"0.2" <= VERSION < v"0.3-"
    # do something specific to 0.2 release series
end

请注意,在上面的示例中v"0.3-",使用了非标准版本号,并带有结尾-:该符号是标准的Julia扩展,用于表示低于任何0.3发行版(包括其所有预发行版)的版本。因此,在上面的示例中,代码将仅以稳定0.2版本运行,而排除诸如之类的版本v"0.3.0-rc1"。为了也允许使用不稳定的0.2版本(即预发行版本),应按如下所示修改下限检查:v"0.2-" <= VERSION

另一种非标准版本规范扩展允许用户使用尾随 来表示构建版本的上限,例如, VERSION > v"0.2-rc1 "可以用于表示以上任何版本0.2-rc1及其任何构建:它将返回falseversion v"0.2-rc1 win64"truefor v"0.2-rc2"

优良作法是在比较中使用这些特殊版本(特别是,-除非有充分的理由,否则应始终在上限处使用尾随),但不得将其用作任何内容的实际版本号,因为它们是无效的在语义版本控制方案中。

除了用于VERSION常量之外,VersionNumber对象还广泛用于Pkg模块中,以指定软件包的版本及其依赖性。

原始字符串文字

没有插值或转义的原始字符串可以用形式为的非标准字符串文字表示raw"..."。原始字符串文字会创建普通String对象,这些对象包含的内含内容与输入的内容完全相同,没有内插或转义。这对于包含以其他语言使用$用作特殊字符的包含代码或标记的字符串很有用。例外是仍然必须转义的引号,例如raw"""等价于"""

0 人点赞