Julia 正则表达式
正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。
Julia 具有与 Perl 兼容的正则表达式 (regexes)。
Julia 的正则表达式的三种形式,分别是匹配,替换和转化:
-
匹配:m/
/(还可以简写为/ /,略去m) -
替换:s/
/ / -
转化:tr/
/ /
这三种形式一般都和 =~ 或 !~ 搭配使用, =~ 表示相匹配,!~ 表示不匹配。
Julia 中正则表达式的输入使用了前缀各类以 r 开头:
实例
r "^ \s *(?:#|$)"
julia > typeof ( re )
Regex
若要检查正则表达式是否匹配某字符串,就用 occursin :
实例
false
julia > occursin ( r "^ \s *(?:#|$)" , "# a comment" )
true
可以看到, occursin 只返回正确或错误,表明给定正则表达式是否在该字符串中出现。然而,通常我们不只想知道字符串是否匹配,更想了解它是如何匹配的。要捕获匹配的信息,可以改用 match 函数:
实例
julia > match ( r "^ \s *(?:#|$)" , "# a comment" )
RegexMatch ( "#" )
若正则表达式与给定字符串不匹配,match 返回 nothing——在交互式提示框中不打印任何东西的特殊值。除了不打印,它是一个完全正常的值,这可以用程序来测试:
实例
if m === nothing
println ( "not a comment" )
else
println ( "blank or comment" )
end
如果正则表达式匹配,match 的返回值是一个 RegexMatch 对象。这些对象记录了表达式是如何匹配的,包括该模式匹配的子字符串和任何可能被捕获的子字符串。上面的例子仅仅捕获了匹配的部分子字符串,但也许我们想要捕获的是注释字符后面的任何非空文本。我们可以这样做:
实例
RegexMatch ( "# a comment " , 1 = "a comment" )
当调用 match 时,你可以选择指定开始搜索的索引。例如:
实例
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 在该处不再包含一个子字符串,而是 什么也不 包含;此外, m.offsets 的偏移量为 0(回想一下,Julia 的索引是从 1 开始的,因此字符串的零偏移是无效的)。下面是两个有些牵强的例子:
实例
RegexMatch ( "acd" , 1 = "a" , 2 = "c" , 3 = "d" )
julia > m.match
"acd"
julia > m.captures
3 - element Vector { Union { Nothing , SubString { String } } } :
"a"
"c"
"d"
julia > m.offset
1
julia > m.offsets
3 - element Vector { Int64 } :
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 Vector { Union { Nothing , SubString { String } } } :
"a"
nothing
"d"
julia > m.offset
1
julia > m.offsets
3 - element Vector { Int64 } :
1
2
让捕获作为数组返回是很方便的,这样就可以用解构语法把它们和局域变量绑定起来。为了方便,RegexMatch 对象实现了传递到 captures 字段的迭代器方法,因此您可以直接解构匹配对象:
实例
"a"
通过使用捕获组的编号或名称对 RegexMatch 对象进行索引,也可实现对捕获的访问:
实例
RegexMatch ( "12:45" , hour = "12" , minute = "45" )
julia > m [ : minute ]
"45"
julia > m [ 2 ]
"45"
使用 replace 时利用 \n 引用第 n 个捕获组和给替换字符串加上 s 的前缀,可以实现替换字符串中对捕获的引用。捕获组 0 指的是整个匹配对象。可在替换中用 \g
julia> replace("first second", r"(\w+) (?<agroup>\w+)" => s"\g<agroup> \1") "second first"
为明确起见,编号捕获组也可用 \g
julia> replace("a", r"." => s"\g<0>1") "a1"
你可以在后双引号的后面加上 i, m, s 和 x 等标志对正则表达式进行修改。
更多正则表达式内容可以参考: 正则表达式 - 教程