Lean 语言参考手册

20.8. 字符串🔗

字符串表示 Unicode 文本。 Lean 对字符串有特殊支持:

  • 它们具有逻辑模型,该模型通过包含 UTF-8 标量值的 ByteArray 来指定其行为。

  • 在编译后的代码中,它们有一个运行时表示,该表示额外包含了一个缓存的长度,以标量值的数量来衡量。 Lean 运行时提供了字符串操作的优化实现。

  • 存在用于编写字符串的字符串字面量语法

UTF-8 是一种可变宽度编码。 一个字符可以编码为一个、两个、三个或四个字节的代码单元。 字符串是 UTF-8 编码的字节数组这一事实在 API 中是可见的:

  • 没有从字符串中提取特定字符的操作,因为这可能是一个性能陷阱。在循环中应使用迭代器而不是 Nat

  • 字符串由 String.Pos 索引,其在内部记录的是字节数而不是字符数,因此需要常量时间。 String.Pos 包含一个证明,证明字节计数实际上指向一个 UTF-8 代码单元的起始位置。 除了 0 之外,这些不应该直接构造,而应该使用 String.nextString.prev 来更新。

20.8.1. 逻辑模型🔗

🔗结构体
String : Type
String : Type

字符串是 Unicode 标量值的序列。

在运行时,字符串由使用 UTF-8 编码的字节的动态数组 表示。以字节为单位的大小 (String.utf8ByteSize) 和以字符为单位的大小 (String.length) 都会被缓存并占用恒定时间。当对字符串的引用是唯一的时,对字符串的许多操作都会执行就地修改。

String.ofByteArray
toByteArray : ByteArray

字符串 UTF-8 编码的字节。由于字符串在运行时采用特殊表示,此函数在运行时实际需要线性时间和空间。若要高效访问字符串的字节,请使用 String.utf8ByteSizeString.getUTF8Byte

isValidUTF8 : self.toByteArray.IsValidUTF8

字符串的字节构成有效的 UTF-8。

Lean 中字符串的逻辑模型是一个包含两个字段的结构体:

此模型允许使用针对字节数组的操作在低级别上指定并证明关于字符串操作的属性,同时仍能建立在字节数组理论之上。 同时,它足够接近真实的运行时表示,从而避免了逻辑模型与运行时表示中有意义的操作之间的阻抗失配。

20.8.1.1. 向后兼容性🔗

在 Lean 的早期版本中,字符串的逻辑模型是包含字符列表的结构体。 该模型仍然有用。 它仍然可以使用 String.ofList(将字符列表转换为 String)以及 String.toList(将 String 转换为字符列表)来访问。

🔗定义

创建一个字符串,其中按顺序包含列表中的字符。

示例:

🔗定义
String.toList (s : String) : List Char
String.toList (s : String) : List Char

将字符串转换为字符列表。

由于字符串表示为包含使用 UTF-8 编码的字符串的动态字节数组,因此此操作所需的时间和空间与字符串的长度成线性关系。

示例:

  • "abc".toList = ['a', 'b', 'c']

  • "".toList = []

  • "\n".toList = ['\n']

20.8.2. 运行时表示🔗

m_header Lean object header m_size Byte countsize_t m_capacity Allocated spacesize_t m_length Characterssize_t m_data String datachar array '\0'
字符串的内存布局

字符串被表示为 UTF-8 编码的字节动态数组。 在对象头部之后,一个字符串包含:

字节数

当前包含有效字符串数据的字节数。

capacity(容量)

目前为该字符串分配的字节数。

length(长度)

编码后字符串的长度,由于 UTF-8 的多字节字符,它可能短于字节数。

data(数据)

字符串中实际的字符数据,以 null 结尾。

Lean 运行时中的许多字符串函数会通过查询对象头部中的引用计数,检查它们是否独占其参数。 如果是这样,并且字符串的容量足够,那么现有的字符串就可以被修改,而不是分配新的内存。 否则,必须分配一个新的字符串。

20.8.2.1. 性能说明🔗

尽管它们看起来像是普通的构造子和投影,但 String.ofByteArrayString.toByteArray 需要的时间与字符串的长度成正比。 这是因为字节数组和字符串没有相同的表示,因此必须将字节数组的内容复制到一个新对象中。

20.8.3. 语法🔗

Lean 有三类字符串字面量:普通字符串字面量、插值字符串字面量和原始字符串字面量。

20.8.3.1. 字符串字面量🔗

字符串字面量以双引号字符 " 开始并结束。 在这两个字符之间,可以包含任意其他字符,包括换行;这些字符都会按字面纳入字符串(但要注意,不论文件编码和平台如何,Lean 源文件中的所有换行都会被解释为 '\n')。 无法直接写入字符串字面量的特殊字符可以用反斜杠转义,因此 "\"Quotes\"" 是一个以双引号开头并以双引号结尾的字符串字面量。 可接受的转义序列形式如下:

\r, \n, \t, \\, \", \'

这些转义序列具有通常的含义,分别对应 CRLF、制表符、反斜杠、双引号和单引号。

\xNN

NN 是由两个十六进制数字组成的序列时,该转义表示 Unicode 码点由这两个十六进制数字给出的字符。

\uNNNN

NN 是由四个十六进制数字组成的序列时,该转义表示 Unicode 码点由这四个十六进制数字给出的字符。

字符串字面量可以包含 间隙。 间隙由一个被转义的换行表示,也就是转义用的反斜杠与换行之间不能有其他字符。 在这种情况下,字面量所表示的字符串会省去该换行以及下一行开头的全部空白。 字符串间隙后面不能跟只含空白字符的行。

这里,str1str2 是同一个字符串:

def str1 := "String with \ a gap" def str2 := "String with a gap" example : str1 = str2 := rfl

如果间隙后紧跟的那一行为空,则该字符串会被拒绝:

def str3 := "String with \unexpected additional newline in string gap 
             a gap"

解析器错误为:

<example>:2:0-3:0: unexpected additional newline in string gap

20.8.3.2. 插值字符串🔗

在字符串字面量前加上 s!,会使其被处理为 插值字符串:字符串中由 {} 包围的部分会被解析并解释为 Lean 表达式。 插值字符串会被解释为:将插值前的字符串、该表达式(外围额外加上一层 toString 调用)以及插值后的字符串依次拼接。

例如:

example : s!"1 + 1 = {1 + 1}\n" = "1 + 1 = " ++ toString (1 + 1) ++ "\n" := rfl

在字面量前加上 m!,会使插值结果成为 MessageData 的一个实例;这是编译器内部用于向用户显示消息的数据结构。

20.8.3.3. 原始字符串字面量🔗

原始字符串字面量 中, 没有转义序列,也没有间隙,每个字符都严格按其自身含义解释。 原始字符串字面量以 r 开头,后跟零个或多个井号字符(#)以及一个双引号 "。 当遇到一个后面紧跟着相同数量井号字符的双引号时,该字符串字面量结束。 例如,它们可用于避免某些字符需要双重转义:

example : r"\t" = "\\t" := rfl "Write backslash in a string using '\\\\\\\\'"#eval r"Write backslash in a string using '\\\\'"

#eval 的结果为:

"Write backslash in a string using '\\\\\\\\'"

加入井号后,字符串中就可以包含无需转义的引号:

example : r#"This is "literally" quoted"# = "This is \"literally\" quoted" := rfl

只要添加足够多的井号,任何原始字面量都可以被按字面写出:

example : r##"This is r#"literally"# quoted"## = "This is r#\"literally\"# quoted" := rfl

20.8.4. API 参考🔗

20.8.4.1. 构造🔗

🔗定义

返回只含字符 c 的新字符串。

此段说明该操作的行为、边界条件及推荐用法。

以下列出相应示例或例外情况。

🔗定义

连接两个字符串,通常通过运算符 ++ 使用。

若相关字符串未被共享,实现会尽可能进行原地更新而不复制。

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"abc".append "def" = "abcdef"。)

  • 示例见所列代码。(相关项:"abc" ++ "def" = "abcdef"。)

  • 示例见所列代码。(相关项:"" ++ "" = ""。)

🔗定义

按顺序连接一个字符串列表中的所有字符串。

可使用所列 API 完成检查、转换或采用更安全的替代方式。(相关项:String.intercalate。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:String.join ["gr", "ee", "n"] = "green"。)

  • 示例见所列代码。(相关项:String.join ["b", "", "l", "", "ue"] = "blue"。)

  • 示例见所列代码。(相关项:String.join [] = ""。)

🔗定义

连接字符串列表中的字符串,并在每一对相邻字符串之间放置分隔符 s

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:", ".intercalate ["red", "green", "blue"] = "red, green, blue"。)

  • 示例见所列代码。(相关项:" and ".intercalate ["tea", "coffee"] = "tea and coffee"。)

  • 示例见所列代码。(相关项:" | ".intercalate ["M", "", "N"] = "M | | N"。)

20.8.4.2. 转换🔗

🔗定义
String.toList (s : String) : List Char
String.toList (s : String) : List Char

把字符串转换为字符列表。

字符串使用 UTF-8 编码;此操作的时间与空间特性如所述。

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"abc".toList = ['a', 'b', 'c']。)

  • 示例见所列代码。(相关项:"".toList = []。)

  • 示例见所列代码。(相关项:"\n".toList = ['\n']。)

🔗定义

检查字符串能否解释为自然数的十进制表示。

此段说明该操作的行为、边界条件及推荐用法。

可使用所列 API 完成检查、转换或采用更安全的替代方式。(相关项:toNat?toNat!。)

示例:

  • 示例见所列代码。(相关项:"".isNat = false。)

  • 示例见所列代码。(相关项:"0".isNat = true。)

  • 示例见所列代码。(相关项:"5".isNat = true。)

  • 示例见所列代码。(相关项:"05".isNat = true。)

  • 示例见所列代码。(相关项:"587".isNat = true。)

  • 示例见所列代码。(相关项:"-587".isNat = false。)

  • 示例见所列代码。(相关项:" 5".isNat = false。)

  • 示例见所列代码。(相关项:"2+3".isNat = false。)

  • 示例见所列代码。(相关项:"0xff".isNat = false。)

🔗定义

把字符串解释为自然数的十进制表示并返回该数;若不是十进制自然数则返回 none

此段说明该操作的行为、边界条件及推荐用法。

可使用所列 API 完成检查、转换或采用更安全的替代方式。(相关项:isNattoNat?sometoNat!none。)

示例:

  • 示例见所列代码。(相关项:"".toNat? = none。)

  • 示例见所列代码。(相关项:"0".toNat? = some 0。)

  • 示例见所列代码。(相关项:"5".toNat? = some 5。)

  • 示例见所列代码。(相关项:"587".toNat? = some 587。)

  • 示例见所列代码。(相关项:"-587".toNat? = none。)

  • 示例见所列代码。(相关项:" 5".toNat? = none。)

  • 示例见所列代码。(相关项:"2+3".toNat? = none。)

  • 示例见所列代码。(相关项:"0xff".toNat? = none。)

🔗定义

把字符串解释为自然数的十进制表示并返回该数;若不是十进制自然数则触发 panic。

此段说明该操作的行为、边界条件及推荐用法。

可使用所列 API 完成检查、转换或采用更安全的替代方式。(相关项:isNattoNat!toNat?none。)

示例:

  • 示例见所列代码。(相关项:"0".toNat! = 0。)

  • 示例见所列代码。(相关项:"5".toNat! = 5。)

  • 示例见所列代码。(相关项:"587".toNat! = 587。)

🔗定义

检查字符串能否解释为整数的十进制表示。

此段说明该操作的行为、边界条件及推荐用法。(相关项:-+。)

可使用所列 API 完成检查、转换或采用更安全的替代方式。(相关项:String.toInt?String.toInt!。)

示例:

  • 示例见所列代码。(相关项:"".isInt = false。)

  • 示例见所列代码。(相关项:"-".isInt = false。)

  • 示例见所列代码。(相关项:"0".isInt = true。)

  • 示例见所列代码。(相关项:"-0".isInt = true。)

  • 示例见所列代码。(相关项:"5".isInt = true。)

  • 示例见所列代码。(相关项:"587".isInt = true。)

  • 示例见所列代码。(相关项:"-587".isInt = true。)

  • 示例见所列代码。(相关项:"+587".isInt = false。)

  • 示例见所列代码。(相关项:" 5".isInt = false。)

  • 示例见所列代码。(相关项:"2-3".isInt = false。)

  • 示例见所列代码。(相关项:"0xff".isInt = false。)

🔗定义

把字符串解释为整数的十进制表示并返回该数;若不是十进制整数则返回 none

此段说明该操作的行为、边界条件及推荐用法。(相关项:-+。)

可使用所列 API 完成检查、转换或采用更安全的替代方式。(相关项:String.isIntString.toInt?someString.toInt!none。)

示例:

  • 示例见所列代码。(相关项:"".toInt? = none。)

  • 示例见所列代码。(相关项:"-".toInt? = none。)

  • 示例见所列代码。(相关项:"0".toInt? = some 0。)

  • 示例见所列代码。(相关项:"5".toInt? = some 5。)

  • 示例见所列代码。(相关项:"-5".toInt? = some (-5)。)

  • 示例见所列代码。(相关项:"587".toInt? = some 587。)

  • 示例见所列代码。(相关项:"-587".toInt? = some (-587)。)

  • 示例见所列代码。(相关项:" 5".toInt? = none。)

  • 示例见所列代码。(相关项:"2-3".toInt? = none。)

  • 示例见所列代码。(相关项:"0xff".toInt? = none。)

🔗定义

把字符串解释为整数的十进制表示并返回该数;若不是十进制整数则触发 panic。

此段说明该操作的行为、边界条件及推荐用法。(相关项:-+。)

可使用所列 API 完成检查、转换或采用更安全的替代方式。(相关项:String.isIntString.toInt!String.toInt?none。)

示例:

  • 示例见所列代码。(相关项:"0".toInt! = 0。)

  • 示例见所列代码。(相关项:"5".toInt! = 5。)

  • 示例见所列代码。(相关项:"587".toInt! = 587。)

  • 示例见所列代码。(相关项:"-587".toInt! = -587。)

🔗定义

把字符串转换为美化打印文档,并用 Std.Format.line 替换字符串中的换行符。

20.8.4.3. 属性🔗

🔗定义

检查字符串是否为空。

空串、前缀、后缀及越界情形按所述规则处理。(相关项:""0。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"".isEmpty = true。)

  • 示例见所列代码。(相关项:"empty".isEmpty = false。)

  • 示例见所列代码。(相关项:" ".isEmpty = false。)

🔗定义

返回字符串包含的 Unicode 码位数量。

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"".length = 0。)

  • 示例见所列代码。(相关项:"abc".length = 3。)

  • 示例见所列代码。(相关项:"L∃∀N".length = 4。)

20.8.4.4. 位置🔗

🔗结构体
String.Pos (s : String) : Type
String.Pos (s : String) : Type

Pos ss 中的字节偏移,并带有该位置位于 UTF-8 字符边界上的证明。

String.Pos.mk
offset : String.Pos.Raw

Pos 的底层字节偏移。

isValid : String.Pos.Raw.IsValid s self.offset

证明 offset 对字符串 s 有效。

20.8.4.4.1. 字符串内🔗

🔗定义

字符串 s 的起始位置,表示为 s.Pos

🔗定义

字符串 s 的越尾位置,表示为 s.Pos

🔗定义
String.pos (s : String) (off : String.Pos.Raw) (h : String.Pos.Raw.IsValid s off) : s.Pos
String.pos (s : String) (off : String.Pos.Raw) (h : String.Pos.Raw.IsValid s off) : s.Pos

根据一个位置及其有效性证明,构造 s 上的有效位置。

🔗定义

根据一个位置构造 s 上的有效位置;若该位置无效则返回 none

🔗定义

根据一个位置构造 s 上的有效位置;若该位置无效则触发 panic。

🔗定义
String.extract {s : String} (b e : s.Pos) : String
String.extract {s : String} (b e : s.Pos) : String

把字符串的一段区域复制到新字符串中。

此段说明该操作的行为、边界条件及推荐用法。(相关项:sbeString。)

在所述条件下,函数按说明返回相应结果或后备结果。(相关项:be""。)

在所述条件下,函数按说明返回相应结果或后备结果。(相关项:String.slice。)

20.8.4.4.2. 查找🔗

🔗定义
String.Pos.get {s : String} (pos : s.Pos) (h : pos s.endPos) : Char
String.Pos.get {s : String} (pos : s.Pos) (h : pos s.endPos) : Char

返回字符串位置 pos 处的字符,并要求证明 p 不是越尾位置。

运行时代码会用高效实现覆盖此函数。

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:("abc".pos 1 (by decide)).get (by decide) = 'b'。)

  • 示例见所列代码。(相关项:("L∃∀N".pos 1 (by decide)).get (by decide) = '∃'。)

🔗定义
String.Pos.get! {s : String} (pos : s.Pos) : Char
String.Pos.get! {s : String} (pos : s.Pos) : Char

返回字符串位置 pos 处的字符;若该位置是越尾位置则触发 panic。

运行时代码会用高效实现覆盖此函数。

🔗定义

返回字符串位置 pos 处的字符;若该位置是越尾位置则返回 none

运行时代码会用高效实现覆盖此函数。

🔗定义
String.Pos.set {s : String} (p : s.Pos) (c : Char) (hp : p s.endPos) : String
String.Pos.set {s : String} (p : s.Pos) (c : Char) (hp : p s.endPos) : String

用新字符替换字符串指定位置处的字符。

若相关字符串未被共享,实现会尽可能进行原地更新而不复制。

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:("abc".pos 1 (by decide)).set 'B' (by decide) = "aBc"。)

  • 示例见所列代码。(相关项:("L∃∀N".pos 4 (by decide)).set 'X' (by decide) = "L∃XN"。)

20.8.4.4.3. 修改🔗

🔗定义
String.Pos.modify {s : String} (p : s.Pos) (f : Char Char) (hp : p s.endPos) : String
String.Pos.modify {s : String} (p : s.Pos) (f : Char Char) (hp : p s.endPos) : String

p 作用于该字符所得的结果,替换字符串 s 中位置 f 处的字符。

若相关字符串未被共享,实现会尽可能进行原地更新而不复制。

以下列出相应示例或例外情况。

🔗定义
String.Pos.byte {s : String} (pos : s.Pos) (h : pos s.endPos) : UInt8
String.Pos.byte {s : String} (pos : s.Pos) (h : pos s.endPos) : UInt8

返回字符串位置 pos 处的字节。

20.8.4.4.4. 调整🔗

🔗定义
String.Pos.prev {s : String} (pos : s.Pos) (h : pos s.startPos) : s.Pos
String.Pos.prev {s : String} (pos : s.Pos) (h : pos s.startPos) : s.Pos

返回给定位置之前的有效位置;所给证明保证当前位置不是起始位置,因此前一位置存在。

🔗定义
String.Pos.prev! {s : String} (pos : s.Pos) : s.Pos
String.Pos.prev! {s : String} (pos : s.Pos) : s.Pos

返回给定位置之前的有效位置;若当前位置是起始位置则触发 panic。

🔗定义
String.Pos.prev? {s : String} (pos : s.Pos) : Option s.Pos
String.Pos.prev? {s : String} (pos : s.Pos) : Option s.Pos

返回给定位置之前的有效位置;若当前位置是起始位置则返回 none

🔗定义
String.Pos.next {s : String} (pos : s.Pos) (h : pos s.endPos) : s.Pos
String.Pos.next {s : String} (pos : s.Pos) (h : pos s.endPos) : s.Pos

把字符串上的有效位置推进到下一个有效位置;所给证明保证当前位置不是越尾位置,因此下一位置存在。

🔗定义
String.Pos.next! {s : String} (pos : s.Pos) : s.Pos
String.Pos.next! {s : String} (pos : s.Pos) : s.Pos

把字符串上的有效位置推进到下一个有效位置;若当前位置是越尾位置则触发 panic。

🔗定义
String.Pos.next? {s : String} (pos : s.Pos) : Option s.Pos
String.Pos.next? {s : String} (pos : s.Pos) : Option s.Pos

把字符串上的有效位置推进到下一个有效位置;若当前位置是越尾位置则返回 none

20.8.4.4.5. 其他字符串🔗

🔗定义
String.Pos.cast {s t : String} (pos : s.Pos) (h : s = t) : t.Pos
String.Pos.cast {s t : String} (pos : s.Pos) (h : s = t) : t.Pos

给定 t 的证明,把 s 上的有效位置转换为 s = t 上的有效位置。

🔗定义

给定切片 s 以及 s.copy 上的位置,取得 s 上的对应位置。

🔗定义
String.Pos.toSetOfLE {s : String} (q p : s.Pos) (c : Char) (hp : p s.endPos) (hpq : q p) : (p.set c hp).Pos
String.Pos.toSetOfLE {s : String} (q p : s.Pos) (c : Char) (hp : p s.endPos) (hpq : q p) : (p.set c hp).Pos

给定字符串中的有效位置,在该位置位于被修改位置之前时,取得设置字符后字符串中的对应位置。

🔗定义
String.Pos.toModifyOfLE {s : String} (q p : s.Pos) (f : Char Char) (hp : p s.endPos) (hpq : q p) : (p.modify f hp).Pos
String.Pos.toModifyOfLE {s : String} (q p : s.Pos) (f : Char Char) (hp : p s.endPos) (hpq : q p) : (p.modify f hp).Pos

给定字符串中的有效位置,在该位置位于被修改位置之前时,取得修改字符后字符串中的对应位置。

🔗定义

把字符串 s 上的有效位置转换为切片 s.toSlice 上的有效位置。

20.8.4.5. 原始位置🔗

🔗结构体

按照 UTF-8 编码表示 String 中字节位置的类型。

此段说明该操作的行为、边界条件及推荐用法。(相关项:NatStringString.Pos.Raw。)

位置或迭代器仅在满足所述边界与 UTF-8 字符边界条件时有效;无效输入的结果按说明处理。(相关项:ps0 p s.rawEndPospString.Pos.IsValid。)

此段说明该操作的行为、边界条件及推荐用法。(相关项:String.PosString.PosString.Pos.Raw。)

String.Pos.Raw.mk
byteIdx : Nat

取得 String.Pos.Raw 的底层字节索引。

20.8.4.5.1. 字节位置🔗

🔗定义

返回字符串中给定位置(即 UTF-8 字节索引)对应的字符索引。

在所述条件下,函数按说明返回相应结果或后备结果。

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"L∃∀N".offsetOfPos 0 = 0。)

  • 示例见所列代码。(相关项:"L∃∀N".offsetOfPos 1 = 1。)

  • 示例见所列代码。(相关项:"L∃∀N".offsetOfPos 2 = 2。)

  • 示例见所列代码。(相关项:"L∃∀N".offsetOfPos 4 = 2。)

  • 示例见所列代码。(相关项:"L∃∀N".offsetOfPos 5 = 3。)

  • 示例见所列代码。(相关项:"L∃∀N".offsetOfPos 50 = 4。)

20.8.4.5.2. 有效性🔗

🔗定义

true 是字符串 p 中有效的 UTF-8 位置,则返回 s

字符串使用 UTF-8 编码;此操作的时间与空间特性如所述。(相关项:p s.rawEndPosp。)

以下列出相应示例或例外情况。

🔗定义

高效检查某位置是否位于切片 s 的 UTF-8 字符边界上。

20.8.4.5.3. 边界🔗

🔗定义

指向字符串末尾、即最后一个字符之后的 UTF-8 字节位置。

  • 示例见所列代码。(相关项:"abc".rawEndPos = 3。)

  • 示例见所列代码。(相关项:"L∃∀N".rawEndPos = 8。)

🔗定义

若指定字节位置大于或等于字符串越尾位置则返回 true,否则返回 false

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:(0 |> "abc".next |> "abc".next |> "abc".atEnd) = false。)

  • 示例见所列代码。(相关项:(0 |> "abc".next |> "abc".next |> "abc".next |> "abc".next |> "abc".atEnd) = true。)

  • 示例见所列代码。(相关项:(0 |> "L∃∀N".next |> "L∃∀N".next |> "L∃∀N".next |> "L∃∀N".atEnd) = false。)

  • 示例见所列代码。(相关项:(0 |> "L∃∀N".next |> "L∃∀N".next |> "L∃∀N".next |> "L∃∀N".next |> "L∃∀N".atEnd) = true。)

  • 示例见所列代码。(相关项:"abc".atEnd 4 = true。)

  • 示例见所列代码。(相关项:"L∃∀N".atEnd 7 = false。)

  • 示例见所列代码。(相关项:"L∃∀N".atEnd 8 = true。)

20.8.4.5.4. 比较🔗

🔗定义

返回 p₁p₂ 中字节索引较小的一个。

🔗定义

返回位置 lohi 所界定字节切片的大小。

🔗定义
String.Pos.Raw.substrEq (s1 : String) (pos1 : String.Pos.Raw) (s2 : String) (pos2 : String.Pos.Raw) (sz : Nat) : Bool
String.Pos.Raw.substrEq (s1 : String) (pos1 : String.Pos.Raw) (s2 : String) (pos2 : String.Pos.Raw) (sz : Nat) : Bool

检查两个字符串的子串是否相等;子串由起始位置及其 UTF-8 字节数指定,任一子串不存在时返回 false

这是旧版 API,未来版本将移除;应优先使用所列的更安全替代方案。(相关项:BEqString.Slice。)

20.8.4.5.5. 调整🔗

🔗定义

返回字符串中指定位置 p 之前的位置。(相关项:p = 00prawEndPospp。)

此段说明该操作的行为、边界条件及推荐用法。(相关项:"L∃∀N".prev 31'∃'。)

这是旧版 API,未来版本将移除;应优先使用所列的更安全替代方案。(相关项:String.Pos.prevString.Pos.prev?String.posString.Pos。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"abc".get ("abc".rawEndPos |> "abc".prev) = 'c'。)

  • 示例见所列代码。(相关项:"L∃∀N".get ("L∃∀N".rawEndPos |> "L∃∀N".prev |> "L∃∀N".prev |> "L∃∀N".prev) = '∃'。)

🔗定义

返回字符串中位置 p 之后的下一个位置。(相关项:pp = s.endPosp。)

此段说明该操作的行为、边界条件及推荐用法。(相关项:pString.next'。)

这是旧版 API,未来版本将移除;应优先使用所列的更安全替代方案。(相关项:String.Pos.nextString.Pos.next?String.posString.ValisPos。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"abc".next 3 = 43 = "abc".endPos。)

  • 示例见所列代码。(相关项:"L∃∀N".next 2 = 32。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"abc".get ("abc".next 0) = 'b'。)

  • 示例见所列代码。(相关项:"L∃∀N".get (0 |> "L∃∀N".next |> "L∃∀N".next) = '∀'。)

🔗定义

返回字符串中位置 p 之后的下一个位置;若 p 无效,结果未指定。

此段说明该操作的行为、边界条件及推荐用法。(相关项:hpString.next。)

def next? (s : String) (p : String.Pos) : Option Char :=
  if h : s.atEnd p then none else s.get (s.next' p h)

这是旧版 API,未来版本将移除;应优先使用所列的更安全替代方案。(相关项:String.next'ifString.Pos.next。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:String.pos。)(相关项:String.Poslet abc := "abc"; abc.get (abc.next' 0 (by decide)) = 'b'。)

🔗定义

String.Pos.Raw.next 一样反复推进位置,同时谓词 p 对当前位置字符返回 false;到达末尾或谓词返回 p 时停止。(相关项:true。)

示例:

  • 示例见所列代码。(相关项:let s := " a "; (Pos.Raw.nextUntil s Char.isWhitespace 0).get s = ' '。)

  • 示例见所列代码。(相关项:let s := " a "; (Pos.Raw.nextUntil s Char.isAlpha 0).get s = 'a'。)

  • 示例见所列代码。(相关项:let s := "a "; (Pos.Raw.nextUntil s Char.isWhitespace 0).get s = ' '。)

🔗定义

String.Pos.Raw.next 一样反复推进位置,同时谓词 p 对当前位置字符返回 true;到达末尾或谓词返回 p 时停止。(相关项:false。)

示例:

  • 示例见所列代码。(相关项:let s := " a "; ((0 : Pos.Raw).nextWhile s Char.isWhitespace).get s = 'a'。)

  • 示例见所列代码。(相关项:let s := "a "; ((0 : Pos.Raw).nextWhile s Char.isWhitespace).get s = 'a'。)

  • 示例见所列代码。(相关项:let s := "ba "; (Pos.Raw.nextWhile s Char.isWhitespace 0).get s = 'b'。)

🔗定义

把位置的字节偏移增加 1;不要与 Pos.next 混淆。

🔗定义

p 向前推进 n 个字节。(相关项:HAddcspp + cp + s。)

此段说明该操作的行为、边界条件及推荐用法。

可使用所列 API 完成检查、转换或采用更安全的替代方式。(相关项:Pos.Raw.offsetBy。)

🔗定义

在左侧用 p 偏移 offset。(相关项:HAddcsc + ps + p。)

此段说明该操作的行为、边界条件及推荐用法。

可使用所列 API 完成检查、转换或采用更安全的替代方式。(相关项:Pos.Raw.increaseBy。)

🔗定义

把位置的字节偏移减少 1;不要与 Pos.prev 混淆。

🔗定义

把位置 p 向后移动 n 个字节。(相关项:HSubcspp - cp - s。)

此段说明该操作的行为、边界条件及推荐用法。

可使用所列 API 完成检查、转换或采用更安全的替代方式。(相关项:Pos.Raw.unoffsetBy。)

🔗定义

p 中减去 offset。(相关项:HSubcsp - cp - s。)

此段说明该操作的行为、边界条件及推荐用法。

可使用所列 API 完成检查、转换或采用更安全的替代方式。(相关项:Pos.Raw.decreaseBy。)

20.8.4.5.6. 字符串查找🔗

🔗定义

创建一个新字符串,内容为输入字符串中由两个位置界定的区域。

位置或迭代器仅在满足所述边界与 UTF-8 字符边界条件时有效;无效输入的结果按说明处理。(相关项:""。)

这是旧版 API,未来版本将移除;应优先使用所列的更安全替代方案。(相关项:String.extractString.SliceString.Slice.copy。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:String.Pos.Raw.extract "red green blue" 0 3 = "red"。)

  • 示例见所列代码。(相关项:String.Pos.Raw.extract "red green blue" 3 0 = ""。)

  • 示例见所列代码。(相关项:String.Pos.Raw.extract "red green blue" 0 100 = "red green blue"。)

  • 示例见所列代码。(相关项:String.Pos.Raw.extract "red green blue" 4 100 = "green blue"。)

  • 示例见所列代码。(相关项:String.Pos.Raw.extract "L∃∀N" 1 2 = "∃∀N"。)

  • 示例见所列代码。(相关项:String.Pos.Raw.extract "L∃∀N" 2 100 = ""。)

🔗定义

返回字符串位置 p 处的字符;若 p 无效,则返回后备值 (default : Char),即 'A',且不触发 panic。

运行时代码会用高效实现覆盖此函数。(相关项:String.Pos.Raw.utf8GetAux。)

这是旧版 API,未来版本将移除;应优先使用所列的更安全替代方案。(相关项:String.Pos.getString.posString.Pos。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"abc".get 1 = 'b'。)

  • 示例见所列代码。(相关项:"abc".get 3 = (default : Char)3。)

  • 示例见所列代码。(相关项:"L∃∀N".get 2 = (default : Char)2'∃'。)

🔗定义

返回字符串位置 p 处的字符;若 p 无效则触发 panic。

可使用所列 API 完成检查、转换或采用更安全的替代方式。(相关项:String.pos?String.Pos.get。)

运行时代码会用高效实现覆盖此函数。(相关项:String.utf8GetAux。)

这是旧版 API,未来版本将移除;应优先使用所列的更安全替代方案。(相关项:String.Pos.getString.pos!String.Pos。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"abc".get! 1 = 'b'。)

🔗定义

返回字符串位置 p 处的字符;若 (default : Char) 无效,则返回 'A',即 p

此段说明该操作的行为、边界条件及推荐用法。(相关项:hpString.get。)

def getInBounds? (s : String) (p : String.Pos) : Option Char :=
  if h : s.atEnd p then none else some (s.get' p h)

围栏之后的边界情况说明仍适用。(相关项:get'if¬ s.atEnd p。)

这是旧版 API,未来版本将移除;应优先使用所列的更安全替代方案。(相关项:p"L∃∀N".get' 2 (by decide) = (default : Char)String.Pos.get。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:String.pos。)

  • 示例见所列代码。(相关项:String.Pos。)(相关项:"abc".get' 0 (by decide) = 'a'let lean := "L∃∀N"; lean.get' (0 |> lean.next |> lean.next) (by decide) = '∀'。)

🔗定义

返回字符串位置 p 处的字符;若 p 无效则返回 none

运行时代码会用高效实现覆盖此函数。(相关项:String.utf8GetAux?。)

这是旧版 API,未来版本将移除;应优先使用所列的更安全替代方案。(相关项:String.Pos.getString.pos?String.Pos。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"abc".get? 1 = some 'b'。)

  • 示例见所列代码。(相关项:"abc".get? 3 = none。)

  • 示例见所列代码。(相关项:"L∃∀N".get? 1 = some '∃'。)

  • 示例见所列代码。(相关项:"L∃∀N".get? 2 = none。)

20.8.4.5.7. 字符串修改🔗

🔗定义

用新字符替换字符串指定位置处的字符;若位置无效,则原样返回字符串。

若相关字符串未被共享,实现会尽可能进行原地更新而不复制。

这是旧版 API,未来版本将移除;应优先使用所列的更安全替代方案。(相关项:String.Pos.setString.posString.Pos。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"abc".set 1 'B' = "aBc"。)

  • 示例见所列代码。(相关项:"abc".set 3 'D' = "abc"。)

  • 示例见所列代码。(相关项:"L∃∀N".set 4 'X' = "L∃XN"。)

  • 示例见所列代码。(相关项:"L∃∀N".set 2 'X' = "L∃∀N"'∃'2。) 以下列出相应示例或例外情况。

🔗定义

p 作用于该字符所得的结果替换字符串 s 中位置 f 处的字符;若 p 无效,则原样返回字符串。

若相关字符串未被共享,实现会尽可能进行原地更新而不复制。

这是旧版 API,未来版本将移除;应优先使用所列的更安全替代方案。(相关项:String.Pos.setString.posString.Pos。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"abc".modify 1 Char.toUpper = "aBc"。)

  • 示例见所列代码。(相关项:"abc".modify 3 Char.toUpper = "abc"。)

20.8.4.6. 查找与修改🔗

选择字符串子区域(例如它的前缀或后缀)的操作会返回原字符串的一个切片,而不是分配一个新字符串。 使用 String.Slice.copy 将切片转换为新字符串。

🔗定义

返回包含 String.Slicen 个字符(Unicode 码位)的 s

在所述条件下,函数按说明返回相应结果或后备结果。(相关项:ns.toList.lengths.toSlice。)

这是廉价操作,因为它不会为结果分配新字符串;需要字符串时可显式复制切片。(相关项:String.Slice.copy。)

示例:

  • 示例见所列代码。(相关项:"red green blue".take 3 == "red".toSlice。)

  • 示例见所列代码。(相关项:"red green blue".take 1 == "r".toSlice。)

  • 示例见所列代码。(相关项:"red green blue".take 0 == "".toSlice。)

  • 示例见所列代码。(相关项:"red green blue".take 100 == "red green blue".toSlice。)

  • 示例见所列代码。(相关项:"مرحبا بالعالم".take 5 == "مرحبا".toSlice。)

🔗定义

创建字符串切片,其中包含 spat 能够匹配(可能反复匹配)的最长前缀。

这是廉价操作,因为它不会为结果分配新字符串;需要字符串时可显式复制切片。(相关项:String.Slice.copy。)

此函数对当前支持的所有模式都是泛型的。

示例:

  • 示例见所列代码。(相关项:"red green blue".takeWhile Char.isLower == "red".toSlice。)

  • 示例见所列代码。(相关项:"red green blue".takeWhile 'r' == "r".toSlice。)

  • 示例见所列代码。(相关项:"red red green blue".takeWhile "red " == "red red ".toSlice。)

  • 示例见所列代码。(相关项:"red green blue".takeWhile (fun (_ : Char) => true) == "red green blue".toSlice。)

🔗定义

返回包含 String.Slicen 个字符(Unicode 码位)的 s

在所述条件下,函数按说明返回相应结果或后备结果。(相关项:ns.toList.lengths.toSlice。)

这是廉价操作,因为它不会为结果分配新字符串;需要字符串时可显式复制切片。(相关项:String.Slice.copy。)

示例:

  • 示例见所列代码。(相关项:"red green blue".takeEnd 4 == "blue".toSlice。)

  • 示例见所列代码。(相关项:"red green blue".takeEnd 1 == "e".toSlice。)

  • 示例见所列代码。(相关项:"red green blue".takeEnd 0 == "".toSlice。)

  • 示例见所列代码。(相关项:"red green blue".takeEnd 100 == "red green blue".toSlice。)

  • 示例见所列代码。(相关项:"مرحبا بالعالم".takeEnd 5 == "لعالم".toSlice。)

🔗定义

创建字符串切片,其中包含 spat 能够匹配(可能反复匹配)的最长后缀。

这是廉价操作,因为它不会为结果分配新字符串;需要字符串时可显式复制切片。(相关项:String.Slice.copy。)

此函数对当前支持的所有模式都是泛型的。

示例:

🔗定义

返回从字符串开头移除指定数量字符(Unicode 码位)后得到的 String.Slice

在所述条件下,函数按说明返回相应结果或后备结果。(相关项:ns.toList.length。)

这是廉价操作,因为它不会为结果分配新字符串;需要字符串时可显式复制切片。(相关项:String.Slice.copy。)

示例:

  • 示例见所列代码。(相关项:"red green blue".drop 4 == "green blue".toSlice。)

  • 示例见所列代码。(相关项:"red green blue".drop 10 == "blue".toSlice。)

  • 示例见所列代码。(相关项:"red green blue".drop 50 == "".toSlice。)

  • 示例见所列代码。(相关项:"مرحبا بالعالم".drop 3 == "با بالعالم".toSlice。)

🔗定义

创建字符串切片,其中从 s 移除了 pat 能够匹配(可能反复匹配)的最长前缀。

这是廉价操作,因为它不会为结果分配新字符串;需要字符串时可显式复制切片。(相关项:String.Slice.copy。)

此函数对当前支持的所有模式都是泛型的。

示例:

  • 示例见所列代码。(相关项:"red green blue".dropWhile Char.isLower == " green blue".toSlice。)

  • 示例见所列代码。(相关项:"red green blue".dropWhile 'r' == "ed green blue".toSlice。)

  • 示例见所列代码。(相关项:"red red green blue".dropWhile "red " == "green blue".toSlice。)

  • 示例见所列代码。(相关项:"red green blue".dropWhile (fun (_ : Char) => true) == "".toSlice。)

🔗定义

返回从字符串末尾移除指定数量字符(Unicode 码位)后得到的 String.Slice

在所述条件下,函数按说明返回相应结果或后备结果。(相关项:ns.toList.length。)

这是廉价操作,因为它不会为结果分配新字符串;需要字符串时可显式复制切片。(相关项:String.Slice.copy。)

示例:

  • 示例见所列代码。(相关项:"red green blue".dropEnd 5 == "red green".toSlice。)

  • 示例见所列代码。(相关项:"red green blue".dropEnd 11 == "red".toSlice。)

  • 示例见所列代码。(相关项:"red green blue".dropEnd 50 == "".toSlice。)

  • 示例见所列代码。(相关项:"مرحبا بالعالم".dropEnd 3 == "مرحبا بالع".toSlice。)

🔗定义

创建字符串切片,其中从 s 移除了 pat 能够匹配(可能反复匹配)的最长后缀。

这是廉价操作,因为它不会为结果分配新字符串;需要字符串时可显式复制切片。(相关项:String.Slice.copy。)

此函数对当前支持的所有模式都是泛型的。

示例:

🔗定义

pat 匹配 s 的前缀,则返回余下部分,否则返回 none

可使用所列 API 完成检查、转换或采用更安全的替代方式。(相关项:String.dropPrefixpat。)

这是廉价操作,因为它不会为结果分配新字符串;需要字符串时可显式复制切片。(相关项:String.Slice.copy。)

此函数对当前支持的所有模式都是泛型的。

示例:

🔗定义

pat 匹配 s 的前缀,则返回余下部分,否则原样返回 s

可使用所列 API 完成检查、转换或采用更安全的替代方式。(相关项:String.dropPrefix?nonepat。)

这是廉价操作,因为它不会为结果分配新字符串;需要字符串时可显式复制切片。(相关项:String.Slice.copy。)

此函数对当前支持的所有模式都是泛型的。

示例:

  • 示例见所列代码。(相关项:"red green blue".dropPrefix "red " == "green blue".toSlice。)

  • 示例见所列代码。(相关项:"red green blue".dropPrefix "reed " == "red green blue".toSlice。)

  • 示例见所列代码。(相关项:"red green blue".dropPrefix 'r' == "ed green blue".toSlice。)

  • 示例见所列代码。(相关项:"red green blue".dropPrefix Char.isLower == "ed green blue".toSlice。)

🔗定义

pat 匹配 s 的后缀,则返回余下部分,否则返回 none

可使用所列 API 完成检查、转换或采用更安全的替代方式。(相关项:String.dropSuffixpat。)

这是廉价操作,因为它不会为结果分配新字符串;需要字符串时可显式复制切片。(相关项:String.Slice.copy。)

此函数对当前支持的所有模式都是泛型的。

示例:

🔗定义

pat 匹配 s 的后缀,则返回余下部分,否则原样返回 s

可使用所列 API 完成检查、转换或采用更安全的替代方式。(相关项:String.dropSuffix?nonepat。)

这是廉价操作,因为它不会为结果分配新字符串;需要字符串时可显式复制切片。(相关项:String.Slice.copy。)

此函数对当前支持的所有模式都是泛型的。

示例:

  • 示例见所列代码。(相关项:"red green blue".dropSuffix " blue" == "red green".toSlice。)

  • 示例见所列代码。(相关项:"red green blue".dropSuffix "bluu " == "red green blue".toSlice。)

  • 示例见所列代码。(相关项:"red green blue".dropSuffix 'e' == "red green blu".toSlice。)

  • 示例见所列代码。(相关项:"red green blue".dropSuffix Char.isLower == "red green blu".toSlice。)

🔗定义

移除字符串首尾的空白字符。

此段说明该操作的行为、边界条件及推荐用法。(相关项:Char.isWhitespacetrue。)

示例:

  • 示例见所列代码。(相关项:"abc".trimAscii == "abc".toSlice。)

  • 示例见所列代码。(相关项:" abc".trimAscii == "abc".toSlice。)

  • 示例见所列代码。(相关项:"abc \t ".trimAscii == "abc".toSlice。)

  • 示例见所列代码。(相关项:" abc ".trimAscii == "abc".toSlice。)

  • 示例见所列代码。(相关项:"abc\ndef\n".trimAscii == "abc\ndef".toSlice。)

🔗定义

返回起始位置为第一个非空白字符的切片,从而移除字符串开头的空白;若不存在非空白字符则以越尾位置为起点。

此段说明该操作的行为、边界条件及推荐用法。(相关项:Char.isWhitespacetrue。)

示例:

🔗定义

返回结束位置为最后一个非空白字符之后的切片,从而移除字符串末尾的空白;若不存在非空白字符则以起始位置为终点。

此段说明该操作的行为、边界条件及推荐用法。(相关项:Char.isWhitespacetrue。)

示例:

🔗定义

一致地减少字符串各行的缩进:从每行开头移除相同数量的空白,使缩进最少的行不再有前导空白。

此段说明该操作的行为、边界条件及推荐用法。(相关项:' ''\t'。)

此段说明该操作的行为、边界条件及推荐用法。

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"Here:\n fun x =>\n x + 1".removeLeadingSpaces = "Here:\nfun x =>\n x + 1"。)

  • 示例见所列代码。(相关项:"Here:\n\t\tfun x =>\n\t \tx + 1".removeLeadingSpaces = "Here:\nfun x =>\n \tx + 1"。)

  • 示例见所列代码。(相关项:"Here:\n\t\tfun x =>\n \n\t \tx + 1".removeLeadingSpaces = "Here:\nfun x =>\n\n \tx + 1"。)

🔗定义

返回 s 的第一个字符;若 s = "",则返回 (default : Char)

示例:

  • 示例见所列代码。(相关项:"abc".front = 'a'。)

  • 示例见所列代码。(相关项:"".front = (default : Char)。)

🔗定义

返回 s 的最后一个字符;若 s = "",则返回 (default : Char)

示例:

  • 示例见所列代码。(相关项:"abc".back = 'c'。)

  • 示例见所列代码。(相关项:"".back = (default : Char)。)

🔗定义
String.find {ρ : Type} {σ : String.Slice Type} [(s : String.Slice) Std.Iterator (σ s) Id (String.Slice.Pattern.SearchStep s)] [(s : String.Slice) Std.IteratorLoop (σ s) Id Id] (s : String) (pattern : ρ) [String.Slice.Pattern.ToForwardSearcher pattern σ] : s.Pos
String.find {ρ : Type} {σ : String.Slice Type} [(s : String.Slice) Std.Iterator (σ s) Id (String.Slice.Pattern.SearchStep s)] [(s : String.Slice) Std.IteratorLoop (σ s) Id Id] (s : String) (pattern : ρ) [String.Slice.Pattern.ToForwardSearcher pattern σ] : s.Pos

查找切片 pattern 中模式 s 的第一次匹配位置;若没有匹配则返回 s.endPos

此函数对当前支持的所有模式都是泛型的。

示例:

  • 示例见所列代码。(相关项:("coffee tea water".find Char.isWhitespace).get! == ' '。)

  • 示例见所列代码。(相关项:"tea".find (fun (c : Char) => c == 'X') == "tea".endPos。)

  • 示例见所列代码。(相关项:("coffee tea water".find "tea").get! == 't'。)

🔗定义
String.revFind? {ρ : Type} {σ : String.Slice Type} [(s : String.Slice) Std.Iterator (σ s) Id (String.Slice.Pattern.SearchStep s)] [(s : String.Slice) Std.IteratorLoop (σ s) Id Id] (s : String) (pattern : ρ) [String.Slice.Pattern.ToBackwardSearcher pattern σ] : Option s.Pos
String.revFind? {ρ : Type} {σ : String.Slice Type} [(s : String.Slice) Std.Iterator (σ s) Id (String.Slice.Pattern.SearchStep s)] [(s : String.Slice) Std.IteratorLoop (σ s) Id Id] (s : String) (pattern : ρ) [String.Slice.Pattern.ToBackwardSearcher pattern σ] : Option s.Pos

从切片末尾向开头遍历,查找模式 pattern 在字符串中的第一次匹配位置;若没有匹配则返回 none

此函数对当前支持的所有模式(所列例外除外)都是泛型的。(相关项:StringString.Slice。)

示例:

🔗定义
String.contains {ρ : Type} {σ : String.Slice Type} [(s : String.Slice) Std.Iterator (σ s) Id (String.Slice.Pattern.SearchStep s)] [(s : String.Slice) Std.IteratorLoop (σ s) Id Id] (s : String) (pat : ρ) [String.Slice.Pattern.ToForwardSearcher pat σ] : Bool
String.contains {ρ : Type} {σ : String.Slice Type} [(s : String.Slice) Std.Iterator (σ s) Id (String.Slice.Pattern.SearchStep s)] [(s : String.Slice) Std.IteratorLoop (σ s) Id Id] (s : String) (pat : ρ) [String.Slice.Pattern.ToForwardSearcher pat σ] : Bool

检查字符串中任意位置是否存在模式 pat 的匹配。

此函数对当前支持的所有模式都是泛型的。

示例:

🔗定义
String.replace.{u_1} {ρ : Type} {σ : String.Slice Type} [(s : String.Slice) Std.Iterator (σ s) Id (String.Slice.Pattern.SearchStep s)] [(s : String.Slice) Std.IteratorLoop (σ s) Id Id] {α : Type u_1} [String.ToSlice α] (s : String) (pattern : ρ) [String.Slice.Pattern.ToForwardSearcher pattern σ] (replacement : α) : String
String.replace.{u_1} {ρ : Type} {σ : String.Slice Type} [(s : String.Slice) Std.Iterator (σ s) Id (String.Slice.Pattern.SearchStep s)] [(s : String.Slice) Std.IteratorLoop (σ s) Id Id] {α : Type u_1} [String.ToSlice α] (s : String) (pattern : ρ) [String.Slice.Pattern.ToForwardSearcher pattern σ] (replacement : α) : String

构造新字符串,把 pattern 中出现的所有 replacement 替换为 s

此函数对当前支持的所有模式都是泛型的。(相关项:StringString.Slice。)

示例:

  • 示例见所列代码。(相关项:"red green blue".replace 'e' "" = "rd grn blu"。)

  • 示例见所列代码。(相关项:"red green blue".replace (fun c => c == 'u' || c == 'e') "" = "rd grn bl"。)

  • 示例见所列代码。(相关项:"red green blue".replace "e" "" = "rd grn blu"。)

  • 示例见所列代码。(相关项:"red green blue".replace "ee" "E" = "red grEn blue"。)

  • 示例见所列代码。(相关项:"red green blue".replace "e" "E" = "rEd grEEn bluE"。)

  • 示例见所列代码。(相关项:"aaaaa".replace "aa" "b" = "bba"。)

  • 示例见所列代码。(相关项:"abc".replace "" "k" = "kakbkck"。)

🔗定义
String.find {ρ : Type} {σ : String.Slice Type} [(s : String.Slice) Std.Iterator (σ s) Id (String.Slice.Pattern.SearchStep s)] [(s : String.Slice) Std.IteratorLoop (σ s) Id Id] (s : String) (pattern : ρ) [String.Slice.Pattern.ToForwardSearcher pattern σ] : s.Pos
String.find {ρ : Type} {σ : String.Slice Type} [(s : String.Slice) Std.Iterator (σ s) Id (String.Slice.Pattern.SearchStep s)] [(s : String.Slice) Std.IteratorLoop (σ s) Id Id] (s : String) (pattern : ρ) [String.Slice.Pattern.ToForwardSearcher pattern σ] : s.Pos

查找切片 pattern 中模式 s 的第一次匹配位置;若没有匹配则返回 s.endPos

此函数对当前支持的所有模式都是泛型的。

示例:

  • 示例见所列代码。(相关项:("coffee tea water".find Char.isWhitespace).get! == ' '。)

  • 示例见所列代码。(相关项:"tea".find (fun (c : Char) => c == 'X') == "tea".endPos。)

  • 示例见所列代码。(相关项:("coffee tea water".find "tea").get! == 't'。)

20.8.4.7. 折叠与聚合🔗

🔗定义
String.map (f : Char Char) (s : String) : String
String.map (f : Char Char) (s : String) : String

把函数 f 应用于字符串中的每个字符,并返回包含所得字符的字符串。

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"abc123".map Char.toUpper = "ABC123"。)

  • 示例见所列代码。(相关项:"".map Char.toUpper = ""。)

🔗定义
String.foldl.{u} {α : Type u} (f : α Char α) (init : α) (s : String) : α
String.foldl.{u} {α : Type u} (f : α Char α) (init : α) (s : String) : α

从开头折叠字符串,以 init 为初值,并用 f 按顺序把每个字符与累积值结合。

示例:

  • 示例见所列代码。(相关项:"coffee tea water".foldl (fun n c => if c.isWhitespace then n + 1 else n) 0 = 2。)

  • 示例见所列代码。(相关项:"coffee tea and water".foldl (fun n c => if c.isWhitespace then n + 1 else n) 0 = 3。)

  • 示例见所列代码。(相关项:"coffee tea water".foldl (·.push ·) "" = "coffee tea water"。)

🔗定义
String.foldr.{u} {α : Type u} (f : Char α α) (init : α) (s : String) : α
String.foldr.{u} {α : Type u} (f : Char α α) (init : α) (s : String) : α

从右侧折叠字符串,以 init 为初值,并用 f 按逆序把每个字符与累积值结合。

示例:

  • 示例见所列代码。(相关项:"coffee tea water".foldr (fun c n => if c.isWhitespace then n + 1 else n) 0 = 2。)

  • 示例见所列代码。(相关项:"coffee tea and water".foldr (fun c n => if c.isWhitespace then n + 1 else n) 0 = 3。)

  • 示例见所列代码。(相关项:"coffee tea water".foldr (fun c s => s.push c) "" = "retaw aet eeffoc"。)

🔗定义
String.all {ρ : Type} (s : String) (pat : ρ) [String.Slice.Pattern.ForwardPattern pat] : Bool
String.all {ρ : Type} (s : String) (pat : ρ) [String.Slice.Pattern.ForwardPattern pat] : Bool

检查字符串是否完全由模式 pat 的匹配组成。

遇到第一个决定结果的值时即短路,并按所述顺序检查元素。

此函数对当前支持的所有模式都是泛型的。

示例:

  • 示例见所列代码。(相关项:"brown".all Char.isLower = true。)

  • 示例见所列代码。(相关项:"brown and orange".all Char.isLower = false。)

  • 示例见所列代码。(相关项:"aaaaaa".all 'a' = true。)

  • 示例见所列代码。(相关项:"aaaaaa".all "aa" = true。)

  • 示例见所列代码。(相关项:"aaaaaaa".all "aa" = false。)

🔗定义
String.any {ρ : Type} {σ : String.Slice Type} [(s : String.Slice) Std.Iterator (σ s) Id (String.Slice.Pattern.SearchStep s)] [(s : String.Slice) Std.IteratorLoop (σ s) Id Id] (s : String) (pat : ρ) [String.Slice.Pattern.ToForwardSearcher pat σ] : Bool
String.any {ρ : Type} {σ : String.Slice Type} [(s : String.Slice) Std.Iterator (σ s) Id (String.Slice.Pattern.SearchStep s)] [(s : String.Slice) Std.IteratorLoop (σ s) Id Id] (s : String) (pat : ρ) [String.Slice.Pattern.ToForwardSearcher pat σ] : Bool

检查字符串中任意位置是否存在模式 pat 的匹配。

此函数对当前支持的所有模式都是泛型的。

示例:

20.8.4.8. 比较🔗

LT String 实例是由基于 LT Char 实例的字符串字典序定义的。 在逻辑上,这是由对建模字符串的列表进行字典序排列来建模的,因此 List.Lex 定义了此顺序。 它是可判定的;在运行时,该判定过程会被利用字符串运行时表示的高效代码替代。

🔗定义
String.le (a b : String) : Prop
String.le (a b : String) : Prop

字符串上的非严格不等关系,通常通过运算符 使用。

此段说明该操作的行为、边界条件及推荐用法。(相关项:a b¬ b < a。)

🔗定义

返回两个字符串首次不同的位置。

在所述条件下,函数按说明返回相应结果或后备结果。

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"tea".firstDiffPos "ten" = 2。)

  • 示例见所列代码。(相关项:"tea".firstDiffPos "tea" = 3。)

  • 示例见所列代码。(相关项:"tea".firstDiffPos "teas" = 3。)

  • 示例见所列代码。(相关项:"teas".firstDiffPos "tea" = 3。)

🔗定义

检查第二个字符串(s)是否以某个前缀(p)开头。

此函数对当前支持的所有模式都是泛型的。

空串、前缀、后缀及越界情形按所述规则处理。(相关项:String.startsWith。)

示例:

  • 示例见所列代码。(相关项:"red".isPrefixOf "red green blue" = true。)

  • 示例见所列代码。(相关项:"green".isPrefixOf "red green blue" = false。)

  • 示例见所列代码。(相关项:"".isPrefixOf "red green blue" = true。)

🔗定义

检查第一个字符串(s)是否以模式(pat)开头。

空串、前缀、后缀及越界情形按所述规则处理。(相关项:String.isPrefixOf。)

示例:

  • 示例见所列代码。(相关项:"red green blue".startsWith "red" = true。)

  • 示例见所列代码。(相关项:"red green blue".startsWith "green" = false。)

  • 示例见所列代码。(相关项:"red green blue".startsWith "" = true。)

  • 示例见所列代码。(相关项:"red green blue".startsWith 'r' = true。)

  • 示例见所列代码。(相关项:"red green blue".startsWith Char.isLower = true。)

🔗定义

检查字符串(s)是否以模式(pat)结尾。

此函数对当前支持的所有模式都是泛型的。

示例:

  • 示例见所列代码。(相关项:"red green blue".endsWith "blue" = true。)

  • 示例见所列代码。(相关项:"red green blue".endsWith "green" = false。)

  • 示例见所列代码。(相关项:"red green blue".endsWith "" = true。)

  • 示例见所列代码。(相关项:"red green blue".endsWith 'e' = true。)

  • 示例见所列代码。(相关项:"red green blue".endsWith Char.isLower = true。)

🔗定义
String.decEq (s₁ s₂ : String) : Decidable (s₁ = s₂)
String.decEq (s₁ s₂ : String) : Decidable (s₁ = s₂)

判定两个字符串是否相等,通常通过 DecidableEq String 实例和运算符 = 使用。

运行时实现具有所述优化与复杂度特性。

🔗不透明定义

计算字符串的哈希值。

20.8.4.9. 操作🔗

🔗定义

p 返回 true 的每个字符处拆分字符串。

空串、前缀、后缀及越界情形按所述规则处理。(相关项:pp。)

这是旧版 API,未来版本将移除;应优先使用所列的更安全替代方案。(相关项:String.split。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"coffee tea water".split (·.isWhitespace) = ["coffee", "tea", "water"]。)

  • 示例见所列代码。(相关项:"coffee tea water".split (·.isWhitespace) = ["coffee", "", "tea", "", "water"]。)

  • 示例见所列代码。(相关项:"fun x =>\n x + 1\n".split (· == '\n') = ["fun x =>", " x + 1", ""]。)

🔗定义
String.splitOn (s : String) (sep : String := " ") : List String
String.splitOn (s : String) (sep : String := " ") : List String

在分隔字符串 s 每次出现的位置拆分字符串 sep;默认分隔符为 " "

在所述条件下,函数按说明返回相应结果或后备结果。(相关项:sep[s]sepn+1nsep。)

这是旧版 API,未来版本将移除;应优先使用所列的更安全替代方案。(相关项:String.split。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"here is some text ".splitOn = ["here", "is", "some", "text", ""]。)

  • 示例见所列代码。(相关项:"here is some text ".splitOn "some" = ["here is ", " text "]。)

  • 示例见所列代码。(相关项:"here is some text ".splitOn "" = ["here is some text "]。)

  • 示例见所列代码。(相关项:"ababacabac".splitOn "aba" = ["", "bac", "c"]。)

🔗定义

在字符串末尾添加一个字符。

若相关字符串未被共享,实现会尽可能进行原地更新而不复制。

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"abc".push 'd' = "abcd"。)

  • 示例见所列代码。(相关项:"".push 'a' = "a"。)

🔗定义
String.pushn (s : String) (c : Char) (n : Nat) : String
String.pushn (s : String) (c : Char) (n : Nat) : String

在字符串末尾添加一个字符的多次重复。

若相关字符串未被共享,实现会尽可能进行原地更新而不复制。(相关项:sncString.push。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"indeed".pushn '!' 2 = "indeed!!"。)

  • 示例见所列代码。(相关项:"indeed".pushn '!' 0 = "indeed"。)

  • 示例见所列代码。(相关项:"".pushn ' ' 4 = " "。)

🔗定义

s 的第一个字符替换为对它应用 Char.toUpper 的结果;若字符串为空则返回空字符串。

此段说明该操作的行为、边界条件及推荐用法。(相关项:Char.toUpper'a''z'。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"orange".capitalize = "Orange"。)

  • 示例见所列代码。(相关项:"ORANGE".capitalize = "ORANGE"。)

  • 示例见所列代码。(相关项:"".capitalize = ""。)

🔗定义

s 的第一个字符替换为对它应用 Char.toLower 的结果;若字符串为空则返回空字符串。

此段说明该操作的行为、边界条件及推荐用法。(相关项:Char.toLower'A''Z'。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"Orange".decapitalize = "orange"。)

  • 示例见所列代码。(相关项:"ORANGE".decapitalize = "oRANGE"。)

  • 示例见所列代码。(相关项:"".decapitalize = ""。)

🔗定义

s 的每个字符替换为对它应用 Char.toUpper 的结果。

此段说明该操作的行为、边界条件及推荐用法。(相关项:Char.toUpper'a''z'。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"orange".toUpper = "ORANGE"。)

  • 示例见所列代码。(相关项:"abc123".toUpper = "ABC123"。)

🔗定义

s 的每个字符替换为对它应用 Char.toLower 的结果。

此段说明该操作的行为、边界条件及推荐用法。(相关项:Char.toLower'A''Z'。)

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"ORANGE".toLower = "orange"。)

  • 示例见所列代码。(相关项:"Orange".toLower = "orange"。)

  • 示例见所列代码。(相关项:"ABc123".toLower = "abc123"。)

20.8.4.10. 遗留迭代器🔗

为了向后兼容,Lean 包含遗留的字符串迭代器。 从根本上说,一个 String.Legacy.Iterator 是一个字符串和该字符串中有效位置的有序对。 迭代器提供了获取当前字符(curr)、替换当前字符(setCurr)、检查迭代器是否可以向左或向右移动(分别为 hasPrevhasNext),以及移动迭代器(分别为 prevnext)的函数。 调用者有责任检查它们是否已经到达字符串的开头或结尾;否则,迭代器确保其位置始终指向一个字符。 然而,String.Legacy.Iterator 不包含这些良构性条件的证明,这可能使其在经验证的代码中更难使用。

🔗结构体

遍历 String 中字符(Unicode 码位)的迭代器,通常由 String.iter 创建。

这是旧版 API,未来版本将移除;应优先使用所列的更安全替代方案。(相关项:String.Possp : s.startPosp.nextp.getp = s.endPosp.IsAtEnd。)

位置或迭代器仅在满足所述边界与 UTF-8 字符边界条件时有效;无效输入的结果按说明处理。

位置或迭代器仅在满足所述边界与 UTF-8 字符边界条件时有效;无效输入的结果按说明处理。(相关项:is0 i s.rawEndPosii = s.rawEndPos。)

以下列出相应示例或例外情况。 以下列出相应示例或例外情况。(相关项:String.Iterator。)

  • 示例见所列代码。(相关项:Iterator.next iteriteriter.atEnd。) 以下列出相应示例或例外情况。(相关项:true。)

  • 示例见所列代码。(相关项:Iterator.forward iter nIterator.nextn iter nn。) 以下列出相应示例或例外情况。

s : String

正在迭代的字符串。

i : String.Pos.Raw

字符串 s 中当前的 UTF-8 字节位置。

不保证此位置对字符串有效。若位置无效,则当前字符为 (default : Char),类似于在无效位置调用 String.get

🔗定义

创建位于字符串开头的迭代器。

这是旧版 API,未来版本将移除;应优先使用所列的更安全替代方案。(相关项:String.Possp : s.startPosp.nextp.getp = s.endPosp.IsAtEnd。)

🔗定义

创建位于字符串开头的迭代器。

这是旧版 API,未来版本将移除;应优先使用所列的更安全替代方案。(相关项:String.Possp : s.startPosp.nextp.getp = s.endPosp.IsAtEnd。)

🔗定义

取得迭代器当前位置处的字符。

这是旧版 API,未来版本将移除;应优先使用所列的更安全替代方案。(相关项:String.Possp : s.startPosp.nextp.getp = s.endPosp.IsAtEnd。)

此段说明该操作的行为、边界条件及推荐用法。(相关项:String.Iterator.curr'。)

在所述条件下,函数按说明返回相应结果或后备结果。(相关项:(default : Char)。)

🔗定义

取得迭代器当前位置处的字符。

此段说明该操作的行为、边界条件及推荐用法。(相关项:it.hasNextString.Iterator.curr。)

🔗定义

检查迭代器是否位于字符串最后一个字符处或其之前。

🔗定义

无条件把迭代器位置向前移动一个字符。

这是旧版 API,未来版本将移除;应优先使用所列的更安全替代方案。(相关项:String.Possp : s.startPosp.nextp.getp = s.endPosp.IsAtEnd。)

位置或迭代器仅在满足所述边界与 UTF-8 字符边界条件时有效;无效输入的结果按说明处理。(相关项:Iterator.atEndfalse。)

🔗定义

无条件把迭代器位置向前移动一个字符。

此段说明该操作的行为、边界条件及推荐用法。(相关项:it.hasNextString.Iterator.next。)

🔗定义

把迭代器位置向前移动指定数量的字符。

位置或迭代器仅在满足所述边界与 UTF-8 字符边界条件时有效;无效输入的结果按说明处理。

🔗定义

把迭代器位置向前移动指定数量的字符。

位置或迭代器仅在满足所述边界与 UTF-8 字符边界条件时有效;无效输入的结果按说明处理。

🔗定义

无条件把迭代器位置向后移动一个字符。

此段说明该操作的行为、边界条件及推荐用法。

🔗定义

把迭代器位置向后移动指定数量的字符,并在字符串开头停止。

🔗定义

检查迭代器是否已越过其字符串的最后一个字符。

🔗定义

替换字符串中的当前字符。

此段说明该操作的行为、边界条件及推荐用法。

🔗定义

向前移动迭代器,直到布尔谓词 p 对当前字符返回 true,或到达字符串末尾;若当前字符已经满足 p,则不做任何操作。

🔗定义
String.Legacy.Iterator.foldUntil.{u_1} {α : Type u_1} (it : String.Legacy.Iterator) (init : α) (f : α Char Option α) : α × String.Legacy.Iterator
String.Legacy.Iterator.foldUntil.{u_1} {α : Type u_1} (it : String.Legacy.Iterator) (init : α) (f : α Char Option α) : α × String.Legacy.Iterator

遍历字符串,在每个字符处用给定函数 f 更新状态,直到 f 返回 none;初始状态为 init。(相关项:fnone。)

🔗定义

提取两个迭代器位置之间的子串;第一个位置为子串开头,第二个位置为子串结尾。

空串、前缀、后缀及越界情形按所述规则处理。

🔗定义

字符串 s 中当前的 UTF-8 字节位置。

位置或迭代器仅在满足所述边界与 UTF-8 字符边界条件时有效;无效输入的结果按说明处理。(相关项:(default : Char)String.get。)

20.8.4.11. 字符串切片🔗

🔗结构体

某个底层字符串的区域或切片。

一个切片由一个字符串以及感兴趣区域的起始和结束字节位置组成。实际提取子字符串需要复制和内存分配,而同一个底层字符串的多个切片可以存在而几乎没有额外开销。虽然可以通过手动跟踪边界来实现,但切片 API 更加方便。

String.Slice 打包证明以确保起始和结束位置始终描绘出一个有效的字符串。出于这个原因,它应该优先于 Substring.Raw 使用。

String.Slice.mk
str : String

底层字符串。

startInclusive : self.str.Pos

字符串切片开始的字节位置。

endExclusive : self.str.Pos

字符串切片结束的字节位置。

startInclusive_le_endExclusive : self.startInclusive  self.endExclusive

该切片不是退化的(但它可能是空的)。

🔗定义

返回包含整个字符串的切片。

🔗定义

p(包括)到s结束的切片。

🔗定义

s 的开头到 p(不含该位置)的切片。

🔗结构体

A Slice.Pos ss 中的一个字节偏移量,并附有证明该位置位于 UTF-8 字符边界处的证明。

offset : String.Pos.Raw

Slice.Pos 的底层字节偏移。

isValidForSlice : String.Pos.Raw.IsValidForSlice s self.offset

证明 offset 对字符串切片 s 是有效的。

20.8.4.11.1. 接口参考🔗

20.8.4.11.1.1. 复制🔗
🔗定义

通过复制字节创建一个 String,字节来自 String.Slice

20.8.4.11.1.2. 大小🔗
🔗定义

检查切片是否为空。

空片有 {name}utf8ByteSize {lean}0

示例:

🔗定义

字符串切片的 UTF-8 编码字节数。

20.8.4.11.1.3. 边界🔗
🔗定义
String.Slice.pos (s : String.Slice) (off : String.Pos.Raw) (h : String.Pos.Raw.IsValidForSlice s off) : s.Pos
String.Slice.pos (s : String.Slice) (off : String.Pos.Raw) (h : String.Pos.Raw.IsValidForSlice s off) : s.Pos

从一个位置和一个关于它有效性的证明构造一个在 s 上有效的位置。

🔗定义

从一个位置构造一个有效的位置 s,如果该位置无效则引发运行时错误。

🔗定义

从一个位置构建一个有效的 s 位置,如果该位置无效,则返回 none

🔗定义

s 的起始位置,作为一个 s.Pos

🔗定义

s 的末端之后位置,作为 s.Pos

🔗定义

切片的结束位置,作为 Pos.Raw

20.8.4.11.1.3.1. 调整🔗
🔗定义

给定一个切片和切片内的有效位置,通过将切片的起始位置替换为给定位置,获取同一底层字符串上的新切片。

🔗定义

给定一个切片和切片内的有效位置,通过将切片的末端替换为给定位置,在相同的底层字符串上获得一个新的切片。

🔗定义
String.Slice.slice (s : String.Slice) (newStart newEnd : s.Pos) (h : newStart newEnd) : String.Slice
String.Slice.slice (s : String.Slice) (newStart newEnd : s.Pos) (h : newStart newEnd) : String.Slice

给定一个切片以及切片内的两个有效位置,获得一个由新边界形成的在相同基础字符串上的新切片。

🔗定义
String.Slice.slice! (s : String.Slice) (newStart newEnd : s.Pos) : String.Slice
String.Slice.slice! (s : String.Slice) (newStart newEnd : s.Pos) : String.Slice

给定一个切片和切片内的两个有效位置,获取由新边界形成的相同底层字符串上的新切片,如果给定的结束位置严格小于给定的起始位置,则触发运行时错误。

🔗定义

从切片的开头移除指定数量的字符(Unicode 代码点)。

如果 n 大于 s 中的字符数,则返回一个空切片。

示例:

🔗定义

从切片的末尾移除指定数量的字符(Unicode 代码点)。

如果 n 大于 s 中的字符数,则返回一个空切片。

示例:

🔗定义

创建一个新切片,包含 spat 匹配的最长后缀(可能重复匹配)。

示例:

🔗定义

如果 pat 匹配 s 的前缀,则返回剩余部分;否则原样返回 s

可使用 String.Slice.dropPrefix? 返回 none,以处理 pat 不匹配前缀的情况。

此函数适用于当前支持的所有模式。

示例:

🔗定义

如果 pat 匹配 s 的前缀,则返回剩余部分;否则返回 none

可使用 String.Slice.dropPrefix 原样返回切片,以处理 pat 不匹配前缀的情况。

此函数适用于当前支持的所有模式。

示例:

🔗定义

如果 pat 匹配 s 的后缀,则返回剩余部分;否则原样返回 s

可使用 String.Slice.dropSuffix? 返回 none,以处理 pat 不匹配后缀的情况。

此函数适用于当前支持的所有模式。

示例:

🔗定义

如果 pat 匹配 s 的后缀,则返回剩余部分;否则返回 none

可使用 String.Slice.dropSuffix 原样返回切片,以处理 pat 不匹配后缀的情况。

此函数适用于当前支持的所有模式。

示例:

🔗定义

创建一个新切片,包含 s 的最长前缀,该前缀与 pat 匹配(可能重复匹配)。

示例:

🔗定义

创建一个包含前 n 个字符(即 s 中的 Unicode 码点)的新切片。

如果 n 大于 s 中的字符数,则返回 s

示例:

🔗定义

创建一个包含后 n 个字符(即 s 中的 Unicode 码点)的新切片。

如果 n 大于 s 中的字符数,则返回 s

示例:

🔗定义

创建一个新切片,包含 s 的后缀前缀,其中 pat 匹配(可能重复)。

此函数适用于所有当前支持的模式。

示例:

🔗定义

创建一个新切片,包含 s 的最长前缀,该前缀与 pat 匹配(可能重复匹配)。

此函数适用于所有当前支持的模式。

示例:

20.8.4.11.1.4. 字符🔗
🔗定义

返回 s 中的第一个字符。如果 s 为空,则返回 (default : Char)

示例:

🔗定义

返回 s 中的第一个字符。如果 s 为空,则返回 none

示例:

🔗定义

返回 s 中的最后一个字符。如果 s 为空,则返回 (default : Char)

示例:

🔗定义

返回 s 中的最后一个字符。如果 s 为空,则返回 none

示例:

20.8.4.11.1.5. 字节🔗
🔗定义

访问字符串切片的 UTF-8 编码中指定的字节。

在运行时,这个函数由高效的、常数时间的代码实现。

🔗定义

访问字符串切片的 UTF-8 编码中指定的字节,如果位置超出范围则会触发 panic。

20.8.4.11.1.6. 位置🔗
🔗定义
String.Slice.posGE (s : String.Slice) (offset : String.Pos.Raw) (h : offset s.rawEndPos) : s.Pos
String.Slice.posGE (s : String.Slice) (offset : String.Pos.Raw) (h : offset s.rawEndPos) : s.Pos

获取大于或等于给定字节位置的最小有效位置。

🔗定义
String.Slice.posGT (s : String.Slice) (offset : String.Pos.Raw) (h : offset < s.rawEndPos) : s.Pos
String.Slice.posGT (s : String.Slice) (offset : String.Pos.Raw) (h : offset < s.rawEndPos) : s.Pos

获取严格大于给定字节位置的最小有效位置。

20.8.4.11.1.7. 搜索🔗
🔗定义
String.Slice.contains {ρ : Type} {σ : String.Slice Type} [(s : String.Slice) Std.Iterator (σ s) Id (String.Slice.Pattern.SearchStep s)] [(s : String.Slice) Std.IteratorLoop (σ s) Id Id] (s : String.Slice) (pat : ρ) [String.Slice.Pattern.ToForwardSearcher pat σ] : Bool
String.Slice.contains {ρ : Type} {σ : String.Slice Type} [(s : String.Slice) Std.Iterator (σ s) Id (String.Slice.Pattern.SearchStep s)] [(s : String.Slice) Std.IteratorLoop (σ s) Id Id] (s : String.Slice) (pat : ρ) [String.Slice.Pattern.ToForwardSearcher pat σ] : Bool

检查切片中是否有模式 pat 的匹配项。

此函数适用于所有当前支持的模式。

示例:

🔗定义

检查切片 (s) 是否以模式 (pat) 开头。

此函数适用于当前支持的所有模式。

示例:

🔗定义

检查切片 (s) 是否以模式 (pat) 结尾。

此函数适用于当前支持的所有模式。

示例:

🔗定义

检查切片是否仅由模式 pat 的匹配项组成。

在第一个模式不匹配时短路。

此函数适用于所有当前支持的模式。

示例:

🔗定义
String.Slice.find? {ρ : Type} {σ : String.Slice Type} [(s : String.Slice) Std.Iterator (σ s) Id (String.Slice.Pattern.SearchStep s)] [(s : String.Slice) Std.IteratorLoop (σ s) Id Id] (s : String.Slice) (pat : ρ) [String.Slice.Pattern.ToForwardSearcher pat σ] : Option s.Pos
String.Slice.find? {ρ : Type} {σ : String.Slice Type} [(s : String.Slice) Std.Iterator (σ s) Id (String.Slice.Pattern.SearchStep s)] [(s : String.Slice) Std.IteratorLoop (σ s) Id Id] (s : String.Slice) (pat : ρ) [String.Slice.Pattern.ToForwardSearcher pat σ] : Option s.Pos

查找模式 pat 在切片 s 中首次匹配的位置。如果没有匹配,则返回 none

此函数适用于所有当前支持的模式。

示例:

🔗定义
String.Slice.revFind? {σ : String.Slice Type} [(s : String.Slice) Std.Iterator (σ s) Id (String.Slice.Pattern.SearchStep s)] [(s : String.Slice) Std.IteratorLoop (σ s) Id Id] {ρ : Type} (s : String.Slice) (pat : ρ) [String.Slice.Pattern.ToBackwardSearcher pat σ] : Option s.Pos
String.Slice.revFind? {σ : String.Slice Type} [(s : String.Slice) Std.Iterator (σ s) Id (String.Slice.Pattern.SearchStep s)] [(s : String.Slice) Std.IteratorLoop (σ s) Id Id] {ρ : Type} (s : String.Slice) (pat : ρ) [String.Slice.Pattern.ToBackwardSearcher pat σ] : Option s.Pos

在切片中查找模式 pat 的第一个匹配位置,从切片末尾开始向起始位置遍历。如果没有匹配,则返回 none

此函数对当前支持的所有模式都是通用的,除了String/String.Slice

示例:

20.8.4.11.1.8. 操作🔗
🔗定义
String.Slice.split {ρ : Type} {σ : String.Slice Type} [(s : String.Slice) Std.Iterator (σ s) Id (String.Slice.Pattern.SearchStep s)] (s : String.Slice) (pat : ρ) [String.Slice.Pattern.ToForwardSearcher pat σ] : Std.Iter String.Slice
String.Slice.split {ρ : Type} {σ : String.Slice Type} [(s : String.Slice) Std.Iterator (σ s) Id (String.Slice.Pattern.SearchStep s)] (s : String.Slice) (pat : ρ) [String.Slice.Pattern.ToForwardSearcher pat σ] : Std.Iter String.Slice

在每个与模式 pat 匹配的子切片处拆分切片。

与模式匹配的子切片不会包含在任何结果子切片中。如果连续多个子切片匹配该模式,结果列表将包含空字符串。

此函数适用于所有当前支持的模式。

示例:

  • ("coffee tea water".toSlice.split Char.isWhitespace).toStringList == ["coffee", "tea", "water"]

  • ("coffee tea water".toSlice.split ' ').toStringList == ["coffee", "tea", "water"]

  • ("coffee tea water".toSlice.split " tea ").toStringList == ["coffee", "water"]

  • ("ababababa".toSlice.split "aba").toStringList == ["coffee", "water"]

  • ("baaab".toSlice.split "aa").toStringList == ["b", "ab"]

🔗定义

在每个匹配模式 pat 的子切片处拆分切片。与 split 不同,匹配的子切片会包含在每个子切片的末尾。

此函数适用于所有当前支持的模式。

示例:

🔗定义

创建一个迭代器,用于遍历 s 中的所有行,并去除行结束字符 \r\n\n

示例:

🔗定义

从切片中移除前导和尾部空白。

“空白字符”被定义为 Char.isWhitespace 返回 true 的字符。

示例:

🔗定义

通过将切片的结束位置移动到最后一个非空白字符来移除切片末尾的空白字符,如果没有非空白字符,则移动到其起始位置。

“空白字符”被定义为 Char.isWhitespace 返回 true 的字符。

示例:

🔗定义

通过将切片的起始位置移动到第一个非空白字符处(如果没有非空白字符,则移动到其结束位置),来移除切片开头的空白字符。

“空白字符”被定义为 Char.isWhitespace 返回 true 的字符。

示例:

20.8.4.11.1.9. 迭代🔗
🔗定义

创建一个迭代器,用于遍历 s 中的所有字符(Unicode 代码点)。

示例:

🔗定义

创建一个迭代器,用于遍历 s 中的所有字符(Unicode 码点),从切片的末尾开始向起始位置迭代。

示例:

🔗定义

创建一个迭代器,用于遍历 {name}s 内的所有有效位置。

示例:

🔗定义

创建一个迭代器,遍历 {name}s 中所有有效位置,从最后一个有效位置开始,向第一个位置迭代。

例子

🔗定义

创建一个遍历 {name}s 中所有字节的迭代器。

示例:

🔗定义

创建一个迭代器,用于遍历 {name}s 中的所有字节,从最后一个开始,向第一个迭代。

示例:

🔗定义

从切片末端向开头遍历,在每个与模式 pat 匹配的子切片处拆分切片。

与模式匹配的子切片不会包含在任何结果子切片中。如果多个连续子切片匹配该模式,结果列表将包含空切片。

此函数适用于当前支持的所有模式,但 String/String.Slice 除外。

示例:

🔗定义
String.Slice.foldl.{u} {α : Type u} (f : α Char α) (init : α) (s : String.Slice) : α
String.Slice.foldl.{u} {α : Type u} (f : α Char α) (init : α) (s : String.Slice) : α

从开始对切片上的函数进行折叠,从 init 开始累积值。累积的值按照顺序与每个字符结合,使用 f

示例:

🔗定义
String.Slice.foldr.{u} {α : Type u} (f : Char α α) (init : α) (s : String.Slice) : α
String.Slice.foldr.{u} {α : Type u} (f : Char α α) (init : α) (s : String.Slice) : α

从末尾对切片上的函数进行折叠,累积一个从 init 开始的值。累积值按照逆序与每个字符结合,使用 f

示例:

20.8.4.11.1.10. 转换🔗
🔗定义

检查切片能否解释为自然数的十进制表示。

切片非空且其中所有字符都是数字时,便可解释为十进制自然数。为便于阅读,可以使用下划线 (_) 分隔数字,但下划线不能位于开头或结尾,也不能连续出现。

使用 toNat?toNat! 将此类切片转换为自然数。

示例:

🔗定义

将切片解释为自然数的十进制表示并返回该自然数。如果切片不包含十进制自然数,则引发运行时错误。

切片非空且其中所有字符都是数字时,便可解释为十进制自然数。可以使用下划线 (_) 分隔数字;解析时会忽略下划线。

使用 isNat 检查 toNat! 是否会返回值。更安全的替代方案是 toNat?:当字符串不是自然数时,它返回 none,而不会引发运行时错误。

示例:

🔗定义

将切片解释为自然数的十进制表示并返回该自然数。如果切片不包含十进制自然数,则返回 none

切片非空且其中所有字符都是数字时,便可解释为十进制自然数。可以使用下划线 (_) 分隔数字;解析时会忽略下划线。

使用 isNat 检查 toNat? 是否会返回 some。 另一种方案是 toNat!:当切片不是自然数时,它会引发运行时错误,而不是返回 none

示例:

20.8.4.11.1.11. 相等性🔗
🔗定义

检查 s1s2 是否表示相同的字符串,即使它们是不同基字符串的切片或同一字符串中的不同切片。

该实现是 s1.copy == s2.copy 的高效等价物

🔗定义

检查 s1 == s2 是否成立,如果忽略 ASCII 大小写。

20.8.4.11.2. 模式🔗

字符串切片支持广义的搜索模式。 许多切片操作并不只针对字符或字符串定义,而是接受任意模式。 通过为本节中的类定义实例,可以让新的类型也成为模式。 Lean 标准库提供了实例,使下列类型既可用于向前搜索,也可用于向后搜索:

模式类型

含义

Char

匹配给定字符

Char Bool

匹配任意满足该谓词的字符

String

匹配给定字符串的出现位置

String.Slice

匹配该切片所表示字符串的出现位置

🔗类型类
String.Slice.Pattern.ToForwardSearcher {ρ : Type} (pat : ρ) (σ : outParam (String.Slice Type)) : Type
String.Slice.Pattern.ToForwardSearcher {ρ : Type} (pat : ρ) (σ : outParam (String.Slice Type)) : Type

提供从模式到 SearchStep 迭代器的转换;该迭代器从 Slice 的开头向末尾搜索模式匹配项。

这些操作可以基于 ForwardPattern 实现,但某些模式可以采用更高效的实现。例如,String 模式搜索器若由字符串的 ForwardPattern 实例派生,就会尝试在字符串的每个位置匹配模式,而已有更高效的字符串匹配方法。Lean 标准库实际使用 Knuth–Morris–Pratt 算法;实现见模块 Init.Data.String.Pattern.String

此类型类可用于提供这样的高效实现。如果不需要这种专门实现,可以使用 ToForwardSearcher.defaultImplementation 自动派生实例。

toSearcher : (s : String.Slice)  Std.Iter (String.Slice.Pattern.SearchStep s)

构建一个迭代器,其产生的 SearchStep 对应于模式 pat 在切片 s 中的各次匹配。该迭代器返回的 SearchStep 所含范围必须 彼此相邻、互不重叠,并覆盖整个 s

🔗类型类
String.Slice.Pattern.ForwardPattern {ρ : Type} (pat : ρ) : Type
String.Slice.Pattern.ForwardPattern {ρ : Type} (pat : ρ) : Type

Slice 的起始提供简单的模式匹配功能。

skipPrefix? : (s : String.Slice)  Option s.Pos

检查切片是否以该模式开始。如果是,则返回移除了前缀的切片;否则结果为 none

skipPrefixOfNonempty? : (s : String.Slice)  s.isEmpty = false  Option s.Pos

检查切片是否以该模式开始。如果是,则返回移除了前缀的切片;否则结果为 none

startsWith : String.Slice  Bool

检查切片是否以该模式开始。

🔗类型类
String.Slice.Pattern.ToBackwardSearcher {ρ : Type} (pat : ρ) (σ : outParam (String.Slice Type)) : Type
String.Slice.Pattern.ToBackwardSearcher {ρ : Type} (pat : ρ) (σ : outParam (String.Slice Type)) : Type

提供从模式到 SearchStep 迭代器的转换;该迭代器从 Slice 的末尾向开头搜索模式匹配项。

这些操作可以基于 BackwardPattern 实现,但某些模式可以采用更高效的实现。例如,String 模式搜索器若由字符串的 BackwardPattern 实例派生,就会尝试在字符串的每个位置匹配模式,而已有更高效的字符串匹配方法。Lean 标准库实际使用 Knuth–Morris–Pratt 算法;实现见模块 Init.Data.String.Pattern.String

此类型类可用于提供这样的高效实现。如果不需要这种专门实现,可以使用 ToBackwardSearcher.defaultImplementation 自动派生实例。

toSearcher : (s : String.Slice)  Std.Iter (String.Slice.Pattern.SearchStep s)

构建一个迭代器,其产生的 SearchStep 对应于模式 pat 在切片 s 中的各次匹配。该迭代器返回的 SearchStep 所含范围必须 彼此相邻、互不重叠,并覆盖整个 s

🔗类型类
String.Slice.Pattern.BackwardPattern {ρ : Type} (pat : ρ) : Type
String.Slice.Pattern.BackwardPattern {ρ : Type} (pat : ρ) : Type

提供从Slice末尾进行简单模式匹配的功能。

skipSuffix? : (s : String.Slice)  Option s.Pos

检查切片是否以该模式结束。如果是,则返回移除该后缀的切片;否则结果为 none

skipSuffixOfNonempty? : (s : String.Slice)  s.isEmpty = false  Option s.Pos

检查切片是否以该模式结束。如果是,则返回移除该后缀的切片;否则结果为 none

endsWith : String.Slice  Bool

检查切片是否以该模式结尾。

20.8.4.11.3. 位置🔗

20.8.4.11.3.1. 查找🔗

由于切片位置保留了对其来源切片的引用,因此可以借助它们查找单个字符或字节。

🔗定义
String.Slice.Pos.byte {s : String.Slice} (pos : s.Pos) (h : pos s.endPos) : UInt8
String.Slice.Pos.byte {s : String.Slice} (pos : s.Pos) (h : pos s.endPos) : UInt8

返回切片中某个位置的字节,该位置不是结束位置。

🔗定义
String.Slice.Pos.get {s : String.Slice} (pos : s.Pos) (h : pos s.endPos) : Char
String.Slice.Pos.get {s : String.Slice} (pos : s.Pos) (h : pos s.endPos) : Char

获取字符串中给定位置的字符。

🔗定义

返回字符串中给定位置的字节;如果该位置是结束位置,则引发运行时错误。

🔗定义

返回字符串中给定位置的字节,如果位置是结尾位置,则返回none

20.8.4.11.3.2. 递增与递减🔗
🔗定义
String.Slice.Pos.prev {s : String.Slice} (pos : s.Pos) (h : pos s.startPos) : s.Pos
String.Slice.Pos.prev {s : String.Slice} (pos : s.Pos) (h : pos s.startPos) : s.Pos

在给定一个证明该位置不是起始位置的前提下,返回给定位置之前的有效位置,这保证了这样的一个位置存在。

🔗定义

返回给定位置之前的上一个有效位置;如果给定位置是起始位置,则引发运行时错误。

🔗定义

返回给定位置之前的上一个有效位置,如果该位置是起始位置,则返回none

🔗定义

迭代 p.prev n 次。

如果这会将 p 移动到 s 的开始之前,结果是 s.endPos

🔗定义
String.Slice.Pos.next {s : String.Slice} (pos : s.Pos) (h : pos s.endPos) : s.Pos
String.Slice.Pos.next {s : String.Slice} (pos : s.Pos) (h : pos s.endPos) : s.Pos

在给定证明该位置不是超出末尾位置的情况下,将有效位置在切片上前进到下一个有效位置,这保证了该位置的存在。

🔗定义

将切片上的有效位置推进到下一个有效位置;如果给定位置是末端之后的位置,则引发运行时错误。

🔗定义

将切片上的有效位置推进到下一个有效位置,或者如果给定位置是超出末尾的位置,则返回 none

🔗定义

将位置 p 前进 n 次。

如果这会将 p 移动到 s 的末尾之后,结果是 s.endPos

20.8.4.11.3.3. 其他字符串或切片🔗
🔗定义
String.Slice.Pos.cast {s t : String.Slice} (pos : s.Pos) (h : s.copy = t.copy) : t.Pos
String.Slice.Pos.cast {s t : String.Slice} (pos : s.Pos) (h : s.copy = t.copy) : t.Pos

t 构造有效位置,依据是 s 上的有效位置以及证明 s.copy = t.copy

🔗定义
String.Slice.Pos.ofSlice {s : String.Slice} {p₀ p₁ : s.Pos} {h : p₀ p₁} (pos : (s.slice p₀ p₁ h).Pos) : s.Pos
String.Slice.Pos.ofSlice {s : String.Slice} {p₀ p₁ : s.Pos} {h : p₀ p₁} (pos : (s.slice p₀ p₁ h).Pos) : s.Pos

给定s.slice p₀ p₁ h中的一个位置,获得s中的对应位置。

🔗定义

给定切片 s 上的有效位置,获取底层字符串 s.str 上对应的有效位置。

🔗定义

给定一个切片 ss 上的一个位置,获取 s.copy. 上的对应位置

🔗定义
String.Slice.Pos.ofSliceFrom {s : String.Slice} {p₀ : s.Pos} (pos : (s.sliceFrom p₀).Pos) : s.Pos
String.Slice.Pos.ofSliceFrom {s : String.Slice} {p₀ : s.Pos} (pos : (s.sliceFrom p₀).Pos) : s.Pos

给定s.sliceFrom p₀中的一个位置,获得s中的对应位置。

🔗定义
String.Slice.Pos.ofSliceTo {s : String.Slice} {p₀ : s.Pos} (pos : (s.sliceTo p₀).Pos) : s.Pos
String.Slice.Pos.ofSliceTo {s : String.Slice} {p₀ : s.Pos} (pos : (s.sliceTo p₀).Pos) : s.Pos

给定s.sliceTo p₀中的一个位置,获得s中的对应位置。

20.8.4.12. 原始子字符串🔗

原生子字符串是一种底层类型,它将字符串与其内部限定某个区域的字节位置组合在一起。 大多数代码应该改用切片,因为它们更安全也更方便。

🔗定义

String 转换为表示整个字符串的 Substring

🔗定义

String 转换为表示整个字符串的 Substring

这是 String.toRawSubstring 的一个不带 @[inline] 注解的版本。

🔗结构体

某些底层字符串的区域或切片。

子字符串包含一个字符串以及感兴趣区域的起始和结束字节位置。实际上提取子字符串需要复制和内存分配,而同一底层字符串可能存在许多子字符串,开销很小,并且它们比手动跟踪边界更方便。

显式使用其构造函数,可以构造一个 Substring,其中一个或两个位置对于字符串无效。如果开始位置和停止位置无效,许多操作将返回意外或令人困惑的结果。因此,Substring 将被弃用,取而代之的是 String.Slice,它始终表示有效的子字符串。

Substring.Raw.mk
str : String

底层字符串。

startPos : String.Pos.Raw

字符串切片起始位置的字节位置。

stopPos : String.Pos.Raw

字符串切片结束位置的字节位置。

20.8.4.12.1. 属性🔗

🔗定义

检查子字符串是否为空。

如果子字符串的开始位置和结束位置相同,则子字符串为空。

🔗定义

字符串的 UTF-8 编码使用的字节数。

20.8.4.12.2. 位置🔗

🔗定义

检查子字符串中的位置是否精确等于其结束位置。

该位置是相对于子字符串的起始位置而不是基础字符串的起始位置来理解的。

🔗定义

返回 cs 中首次出现位置相对于子字符串的位置;若 s.bsize 之前未出现 c,则返回该值。

🔗定义

返回子字符串中给定位置之后的下一个位置。如果位置位于子字符串的末尾,则原样返回。

输入位置和返回位置都是相对于子字符串的起始位置而不是基础字符串进行解释的。

🔗定义

返回子字符串中从给定位置向前指定字符数的位置。如果到达子字符串的结束位置,则返回该子字符串。

输入位置和返回位置都是相对于子字符串的起始位置而不是基础字符串进行解释的。

🔗定义

返回子字符串中给定位置之前的上一个位置。如果位置位于子字符串的开头,则原样返回。

输入位置和返回位置都是相对于子字符串的起始位置而不是基础字符串进行解释的。

🔗定义

返回子字符串中给定位置之前指定字符数的位置。如果到达子字符串的起始位置,则返回该子字符串。

输入位置和返回位置都是相对于子字符串的起始位置而不是基础字符串进行解释的。

20.8.4.12.3. 归折与聚合🔗

🔗定义
Substring.Raw.foldl.{u} {α : Type u} (f : α Char α) (init : α) (s : Substring.Raw) : α
Substring.Raw.foldl.{u} {α : Type u} (f : α Char α) (init : α) (s : Substring.Raw) : α

将函数折叠到左侧的子字符串上,累加以 init 开头的值。累加值按顺序与每个字符组合,使用 f

🔗定义
Substring.Raw.foldr.{u} {α : Type u} (f : Char α α) (init : α) (s : Substring.Raw) : α
Substring.Raw.foldr.{u} {α : Type u} (f : Char α α) (init : α) (s : Substring.Raw) : α

将函数折叠到右侧的子字符串上,累加以 init 开头的值。使用 f 将累积值与每个字符按相反顺序组合。

🔗定义

检查布尔谓词 p 是否为子字符串中的每个字符返回 true

p 返回 false 的第一个字符处短路。

🔗定义

检查布尔谓词 p 是否为子字符串中的任何字符返回 true

p 返回 true 的第一个字符处短路。

20.8.4.12.4. 比较🔗

🔗定义

检查两个子字符串是否表示相等的字符串。通常通过 == 运算符访问。

两个子字符串不需要具有相同的底层字符串或相同的开始和结束位置;相反,如果它们包含相同的字符序列,则它们相等。

🔗定义

检查两个子字符串是否具有相同的位置和内容。

两个子字符串不需要具有相同的基础字符串即可使此检查成功。

20.8.4.12.5. 前缀与后缀🔗

🔗定义

返回两个子字符串的最长公共前缀。

返回的子字符串使用与 s 相同的基础字符串。

🔗定义

返回两个子字符串的最长公共后缀。

返回的子字符串使用与 s 相同的基础字符串。

🔗定义

如果 pres 的前缀,则返回剩余部分,否则返回 none

子字符串 pres 的前缀,当且仅当存在 t : Substring 使得 s.toString = pre.toString ++ t.toString。此时结果是 s 去掉该前缀后的子字符串。

🔗定义

如果 suffs 的后缀,则返回剩余部分,否则返回 none

子字符串 suffs 的后缀,当且仅当存在 t : Substring 使得 s.toString = t.toString ++ suff.toString。此时结果是 s 去掉该后缀后的子字符串。

20.8.4.12.6. 查找🔗

🔗定义

返回子字符串中给定位置的字符。

该位置是相对于子字符串而不是基础字符串的,并且不会针对子字符串的结束位置执行边界检查。如果相对位置不是基础字符串中的有效位置,则返回回退值 (default : Char),即 'A'。 不惊慌。

🔗定义

检查子字符串是否包含指定字符。

🔗定义

返回子字符串中的第一个字符。

如果子字符串为空,但子字符串的起始位置是基础字符串中的有效位置,则返回起始位置处的字符。如果子字符串的起始位置不是字符串中的有效位置,则返回回退值 (default : Char),即 'A'。 不惊慌。

20.8.4.12.7. 修改🔗

🔗定义

通过向前移动子字符串的起始位置,从子字符串的开头删除指定数量的字符(Unicode 代码点)。

如果到达子字符串的结束位置,则起始位置不会提前超过它。

🔗定义

通过移动子字符串的起始位置,删除其中布尔谓词为所有字符返回 true 的子字符串的最长前缀。起始位置将移动到谓词返回 false 的第一个字符的位置,或者如果谓词始终返回 true,则移动到子字符串的结束位置。

🔗定义

通过将子字符串的结束位置移向其开始位置,从子字符串的末尾删除指定数量的字符(Unicode 代码点)。

如果到达子字符串的起始位置,则结束位置不会缩回超过它。

🔗定义

通过移动子字符串的结束位置,删除其中布尔谓词为所有字符返回 true 的子字符串的最长后缀。结束位置将移动到谓词返回 false 的最后一个字符的位置之后,或者如果谓词始终返回 true,则移动到子字符串的开始位置。

🔗定义

通过将子字符串的结束位置移向开始位置,仅保留子字符串开头的指定数量的字符(Unicode 代码点)。

如果到达子字符串的起始位置,则结束位置不会缩回超过它。

🔗定义

仅保留子字符串的最长前缀,其中布尔谓词通过将子字符串的结束位置移向其开始位置来为所有字符返回 true

🔗定义

通过将子字符串的起始位置移向结束位置,仅保留子字符串末尾指定数量的字符(Unicode 代码点)。

如果到达子字符串的结束位置,则起始位置不会提前超过它。

🔗定义

仅保留子字符串的最长后缀,其中布尔谓词通过将子字符串的起始位置移向其结束位置来为所有字符返回 true

🔗定义

以子字符串的形式返回由提供的开始位置和停止位置分隔的子字符串区域。这些位置是根据子字符串的起始位置而不是底层字符串来解释的。

如果生成的子字符串为空,则生成的子字符串是空字符串 "" 的子字符串。否则,底层字符串是输入子字符串的起始位置和结束位置已调整的字符串。

🔗定义

通过首先将其起始位置移动到第一个非空白字符,然后将其结束位置移动到最后一个非空白字符,从子字符串中删除前导和尾随空白。

如果子字符串仅包含空格,则生成的子字符串的起始位置将移动到其结束位置。

“空白”定义为 Char.isWhitespace 返回 true 的字符。

示例:

🔗定义

通过将子字符串的起始位置移动到第一个非空格字符,或者如果没有非空格字符,则移动到其结束位置,从而删除子字符串中的前导空格。

“空白”定义为 Char.isWhitespace 返回 true 的字符。

🔗定义

通过将子字符串的结束位置移动到最后一个非空格字符,或者如果没有非空格字符,则移动到其开始位置,从而删除子字符串中的尾随空格。

“空白”定义为 Char.isWhitespace 返回 true 的字符。

🔗定义

在子字符串 s 中每次出现分隔符字符串 sep 的位置进行拆分。默认分隔符是 " "

sep 为空时,结果为 [s]。当 sep 以重叠模式出现时,采用首个匹配。如果存在 n+1 个返回元素,则恰好存在 n 个非重叠的 sep 匹配。分隔符不会包含在返回的子字符串中,而这些子字符串全都是 s 的底层字符串的子字符串。

🔗定义

给定一个 Substring,返回另一个具有有效端点并根据 Substring.toString 表示相同子字符串的值。 (注意,子字符串仍然可能是反转的,即开始大于结束。)

20.8.4.12.8. 转换🔗

🔗定义

{} 将子字符串指向的基础字符串区域复制到新字符串中。

🔗定义

检查子字符串是否可以解释为自然数的十进制表示形式。

如果子字符串不为空并且其中的所有字符都是数字,则可以将其解释为十进制自然数。为了便于阅读,允许使用下划线 ({lit}_) 作为数字分隔符,但不能出现在开头、结尾或连续。

使用 Substring.toNat? 将此类子字符串转换为自然数。

🔗定义

检查子字符串是否可以解释为自然数的十进制表示形式,如果可以则返回该数字。

如果子字符串不为空并且其中的所有字符都是数字,则可以将其解释为十进制自然数。下划线 ({lit}_) 允许作为数字分隔符,但在解析过程中会被忽略。

使用Substring.isNat检查子串是否是这样的子串。

🔗定义

返回一个迭代器到底层字符串的子字符串的起始位置。结束位置被丢弃,因此不能单独使用迭代器来确定其当前位置是否在原始子字符串内。

🔗定义

将子字符串转换为 Lean 编译器中的名称表示。所得名称具有层级结构,字符串会在点号('.')处分段。

"a.b".toRawSubstring.toName 得到名称 a.b,而非 «a.b»。若要得到后者,请使用 Name.mkSimple Substring.Raw.toString。 -- 此旧名称计划弃用

20.8.4.13. 元编程🔗

🔗定义
String.toName (s : String) : Lean.Name
String.toName (s : String) : Lean.Name

把字符串转换为 Lean 编译器使用的名称表示;所得名称具有层次结构,并在点号('.')处拆分字符串。

此段说明该操作的行为、边界条件及推荐用法。(相关项:"a.b".toNamea.b«a.b»Name.mkSimple。)

🔗定义

把字符串转换为相应的 Lean 字符串字面量语法:两端添加双引号,并按需转义内部字符。

以下列出相应示例或例外情况。

  • 示例见所列代码。(相关项:"abc".quote = "\"abc\""。)

  • 示例见所列代码。(相关项:"\"".quote = "\"\\\"\""。)

20.8.4.14. 编码🔗

🔗定义

访问字符串 UTF-8 编码中指定的字节。

运行时代码会用高效实现覆盖此函数。

🔗定义

返回字符串的 UTF-8 编码所占的字节数。

运行时实现具有所述优化与复杂度特性。

🔗定义

返回字符的 UTF-8 编码中的字节序列。

🔗定义
String.fromUTF8 (a : ByteArray) (h : a.IsValidUTF8) : String
String.fromUTF8 (a : ByteArray) (h : a.IsValidUTF8) : String

把以 UTF-8 编码字符串的字节数组解码为相应字符串。(相关项:相关说明。)

🔗定义

把以 UTF-8 编码字符串的字节数组解码为相应字符串;若数组不是有效的 UTF-8 字符串编码则返回 none。(相关项:相关说明。)

🔗定义

把以 UTF-8 编码字符串的字节数组解码为相应字符串;若数组不是有效的 UTF-8 字符串编码则触发 panic。(相关项:相关说明。)

🔗定义

把字符串编码为 UTF-8 字节数组。

🔗定义

把每个 \r\n 替换为 \n 以规范化行尾,但不检查是否存在孤立的 \r 字符。

此段说明该操作的行为、边界条件及推荐用法。(相关项:String.replace text "\r\n" "\n"。)

20.8.5. 外部函数接口(FFI)🔗

FFI type
typedef struct {
    lean_object m_header;
    /* 字节长度,包含 '\0' 终止符 */
    size_t      m_size;
    size_t      m_capacity;
    /* UTF8 长度 */
    size_t      m_length;
    char        m_data[0];
} lean_string_object;

这是字符串在 C 中的表示。更多细节参见 运行时 String 的说明。

FFI function
bool lean_is_string(lean_object * o)

返回值为 true 当且仅当 o 是字符串;否则返回 false

FFI function
lean_string_object * lean_to_string(lean_object * o)

在运行时检查 o 是否确为字符串。若 o 不是字符串,则断言失败。