raku正则文档翻译-暂停!AI代替

杂项-raku正则文档翻译-暂停!AI代替

概述:针对字符数据的模式匹配

正则表达式是一串确定特殊文本模型的字符序列,特别是在大型文本内容中。

在理论计算学和一般语言学中,正则表达式过去被称为正则语言。因为在1950年代,他们开创了对于正则表达式的切实可行的实现,例如的文本编辑器中的搜索和替换,不过需要繁琐的严格科学定义。为了消除歧义,raku语言和其他编程语言一样称之为R.egex。

在raku语言中,Regex被设计为特定领域子语言,即子语言或者Slang(sublanguag)。

词法约定

从根本上上来说,raku Regex和子程序很相似:都有代码对象,并且可以匿名或者命名正则表达式。

一个正则表达式,无论是匿名或者命名,都是代表了Regex Object,但构造匿名或命名Regex Object 是不同的。

匿名正则语法


rx/pattern/;          # 一个匿名正则表达式; 'rx' 代表 'regex'
/pattern/;            # 简写

regex { pattern };    # 关键字定义;


rx/pattern/;  相比较简写方式,有两个优点。

第一,可以使用除了 /  外其他类型的分割符号,以增强正则表达式可读性。


rx{ '/tmp/'.* };      花括号的分割,对于斜杠的分割,明显有更好的可读性。
rx/ '/tmp/'.* /;


但尽管选择广泛,但是依旧并不是没有符号都可以作为分隔符。

  1. 你不能使用 空格 和 字母数字 作为分隔符。空格在正则定义语法中通常是可选的,特别是在需要区分function call 语法时。
  2. 小括号可以作为分割符号,但需要在 rx 和分隔符之间留有空间。这是因为 rx() 会被解析为 call operator 进行调用操作。
  3. 使用 : 冒号是禁止,因为 它是作为  :adverbs 进行使用。
  4. # 也是不行,因为会被作为注释解释。

第二,你可以在rx 和分隔符之间插入:adverbs 这样或许有更好的可读性。


rx:r:s/pattern/;            # :r (:ratchet) and :s (:sigspace) adverbs, 定义空格时是显著可读。

rx/:r:s pattern/;           # 相同,但是可读性更差。


note:虽然匿名正则表达式没有名字,但是可以通过放入变量中赋予名字,并且可以作为插值被引用,无论是在嵌入正则表达式外面还是里面。


my $regex = / R \w+ /;
say "Zen Buddhists like Raku too" ~~ $regex; # OUTPUT: «「Raku」␤»

my $regex = /pottery/;
"Japanese pottery rocks!" ~~ / <$regex> /;  # Interpolation of $regex into /.../
say $/;                                     # OUTPUT: «「pottery」␤»


命名正则语法

regex R {pattern}; # 一个Regex Object,名字为 R

不像匿名正则,你不能选择其他的分隔符,花括号是必须的。在这一点上,命名正则语法和子程序语法类似,使用 regex 关键字作为定义。

my sub   S { /pattern/ };   # definition of Sub object (returning a Regex)
my regex R {  pattern  };   # definition of Regex object


这强调了Regex Object是代码而不是数据。

&S ~~ Code;                 # OUTPUT: «True␤»
&R ~~ Code;                 # OUTPUT: «True␤»
&R ~~ Method;               # OUTPUT: «True␤»   (A Regex is really a Method!)

命名正则并不允许在分隔符之前插入adverbs,相反,可能位于分隔符内整个正则表达式的开始。

regex R { :i pattern };     # :i (:ignorecase), renders pattern case insensitive

正则可读性:空格和注释

空格在正则表达式被忽略,除非使用 :sigspace 副词,使得空格在格式上有明显意义。

另外,除了空格之外,还可以在正则表达式内部使用注释来提高它们的可理解性,就像在一般代码中一样。对于单行注释和多行/嵌入注释都是如此。

my $regex =  rx/ \d ** 4            #`(match the year YYYY)
                 '-'
                 \d ** 2            # ...the month MM
                 '-'
                 \d ** 2 /;         # ...and the day DD

say '2015-12-25'.match($regex);     # OUTPUT: «「2015-12-25」␤»

语法匹配

对于字符串匹配正则表达式,有多种选择方式。不考虑其他语法选择,一个成功的匹配结果会在Match对象中;如果失败,匹配结果回事 Nil。匹配结果可以通过特殊变量 $/ 进行获取。

匹配方式主要有以下:

Smartching

_"string" ~~ /pattern/, or "string" ~~ /<R>/_


say "Go ahead, make my day." ~~ / \w+ /;   # OUTPUT: «「Go」␤»

my regex R { me|you };
say "You talkin' to me?" ~~ / <R> /;       # OUTPUT: «「me」␤ R => 「me」␤»
say "May the force be with you." ~~ &R ;   # OUTPUT: «「you」␤»

Explicit topic match

_m/pattern/, or m/<R>/_

m/  / 立即与特殊变量 $_ 进行正则匹配。并且,和rx/ / 一样,在分隔符和 rx 可以使用adverbs

m/ / 与 / /的区别在于,m/ /执行匹配,而不是表达式。

my $match;
$_ = "abc";
$match = m/.+/; say $match; say $match.^name; # OUTPUT: «「abc」␤Match␤»
$match =  /.+/; say $match; say $match.^name; # OUTPUT: «/.+/␤Regex␤»

Implicit topic match

一些正则表达式在_sink and Boolean contexts 中,特殊变量 $_ 将自动匹配它_


$_ = "dummy string";        # Set the topic explicitly

rx/ s.* /;                  # Regex object in sink context matches automatically
say $/;                     # OUTPUT: «「string」␤»

say $/ if rx/ d.* /;        # Regex object in Boolean context matches automatically
                            # OUTPUT: «「dummy string」␤»


Match method

_"string".match: /pattern/, or "string".match: /<R>/_

正则表达式作为参数,被“string”匹配调用。

Parsing grammars

_grammar-name.parse($string)_

详情见raku grammar部分

字面值 and metacharacters

字符组

\d and \D

posted @ 2025-11-19 11:28  no_no  阅读(11)  评论(0)    收藏  举报