List 转换一个单词';用Raku将字符简明地输入其ascii代码列表
我正在尝试将单词wall转换为其ascii代码列表List 转换一个单词';用Raku将字符简明地输入其ascii代码列表,list,raku,List,Raku,我正在尝试将单词wall转换为其ascii代码列表(119、97、108、108),如下所示: my @ascii="abcdefghijklmnopqrstuvwxyz"; my @tmp; map { push @tmp, $_.ord if $_.ord == @ascii.comb.any.ord }, "wall".comb; say @tmp; 有没有一种方法可以使用@tmp而不在单独的行中声明它 有没有办法在一行而不是三行中生成asci
(119、97、108、108)
,如下所示:
my @ascii="abcdefghijklmnopqrstuvwxyz";
my @tmp;
map { push @tmp, $_.ord if $_.ord == @ascii.comb.any.ord }, "wall".comb;
say @tmp;
@tmp
而不在单独的行中声明它
请注意,我必须使用
@ascii
变量,也就是说,我不能使用连续递增的ascii序列(97、98、99…122)
,因为我计划将此代码也用于非ascii语言。在这里我们可以做一些事情来使其工作
首先,让我们处理@ascii
变量。@
符号表示位置变量,但您为其指定了一个字符串。这将创建一个1元素数组['abc…']
,这将导致以后的问题。根据需要的通用性,我建议直接创建阵列:
my @ascii = <a b c d e f g h i j k l m n o p q r s t u v x y z>;
my @ascii = 'a' .. 'z';
my @ascii = 'abcdefghijklmnopqrstuvwxyz'.comb;
在这里,我使用了$
符号,因为any
确实指定了任何单个值,因此它的功能也是如此(这也让我们的生活更轻松)。我个人会使用$ascii
,但我会使用一个单独的名称,以使后面的示例更易于区分
现在我们可以处理map函数了。基于上述两个版本的ascii,我们可以将map函数重写为以下任意一种
{ push @tmp, $_.ord if $_ eq @ascii.any }
{ push @tmp, $_.ord if $_ eq $ascii-char }
请注意,如果您喜欢使用==
,您可以继续在初始ascii
创建中创建数值,然后使用$.ord
。此外,就我个人而言,我喜欢命名映射变量,例如:
{ push @tmp, $^char.ord if $^char eq @ascii.any }
{ push @tmp, $^char.ord if $^char eq $ascii-char }
其中,$^foo
替换了$
(如果您使用了多个,它们会将字母顺序映射到@[0]
,@[1]
,等等)
但让我们来看一个更有趣的问题。我们怎样才能做到这一切而不需要预先声明@tmp
?显然,这只需要在map循环中创建数组。当我们没有ASCII值时,您可能会认为这可能很棘手,但是if
语句如果不运行,则返回空的(或()
)这一事实让生活变得非常简单:
my @tmp = map { $^char.ord if $^char eq $ascii-char }, "wall".comb;
my @tmp = map { $^char.ord if $^char eq @ascii.any }, "wall".comb;
如果我们使用“wáll”,则map
收集的列表将是119,空,108,108
,自动返回为119,108,108
。因此,@tmp
被设置为仅119108108
是的,有一种更简单的方法
“wall.ords.grep('az'.ords.minmax));
当然,这取决于a
到z
是一个完整的序列。这是因为minmax
基于列表中的最小值和最大值创建范围对象
如果它们不是在一个完整的序列中,你可以使用一个连接
“wall.ords.grep('az'.ords.minmax |'az'.ords.minmax);
但是你说你想和其他语言相匹配。对我来说,这叫雷格克斯
“wall.comb.grep(/^&$/).map(*.ord)
这与同样使用ASCII的小写字母相匹配
事实上,我们可以让它变得更简单comb
可以接受一个正则表达式,该正则表达式确定从输入中提取哪些字符
“墙”.comb(/&/).map(*.ord)
# (119, 97, 108, 108)
“ΔαβγΔε”.comb(/&/).map(*.ord)
# (945, 946, 947, 948, 949)
#不包括Γ或Δ,因为它们不是小写
请注意,如果您没有组合重音,以上仅适用于ASCII
“de\c[组合尖锐重音]f”。梳(/&/)
#(“d”、“f”)
组合锐音重音与e
组合,构成带锐音的拉丁文小写字母e。
该组合字符不是ASCII格式,因此将跳过它
如果角色没有一个组合值,它会变得更奇怪
“f\c[组合急性重音]”.comb(/&/)
#(“f́”,)
这是因为f
是小写的,并且是ASCII格式。不过,编写代码点会被带到车上
基本上,如果您的数据有,或者可以有组合重音,并且如果它可以破坏东西,那么您最好在它仍然是二进制形式时处理它
$buf.grep:{
.uniprop()等式'Ll'#
&&.uniprop('Block')eq“基本拉丁语”#ASCII
}
上述方法也适用于单字符字符串,因为.uniprop
适用于表示码点的整数或实际字符
“墙”。comb.grep:{
.uniprop()等式'Ll'#
&&.uniprop('Block')eq“基本拉丁语”#ASCII
}
请再次注意,这与编写代码点有相同的问题,因为它可以处理字符串
您可能还想使用.uniprop('Script')
而不是.uniprop('Block')
,具体取决于您想要执行的操作。以下是使用Raku的trans
方法的工作方法(在Raku REPL中执行的代码片段):
>my@a=“wall”.comb;
[w a l]
>@a.trans('abcdefghijklmnopqrstuvwxyz'=>ords('abcdefghijklmnopqrstuvwxyz')).put;
119 97 108 108
上面,我们处理一个ascii字符串。下面我添加了“é”字符,并展示了一个两步解决方案:
>my@a=“wallé”.comb;
[w a lé]
>my@b=@a.trans('abcdefghijklmnopqrstuvxyz'=>ords('abcdefghijklmnopqrstuvxyz');
[119 97 108 108 é]
>@b.trans(“é”=>ords(“é”).put
119 97 108 108 233
注1:尽管上面所有的代码都很好,但当我尝试将字母表缩短为'a'..'z'
时,我发现返回值错误…因此使用了完整的'abcdefghijklmnopqrstuvxyz'
注2:我脑海中的一个问题是,当trans
无法识别字符时,试图抑制输出(例如,如何抑制将“é”指定为最后一个元素)
my @tmp = map { $^char.ord if $^char eq $ascii-char }, "wall".comb;
my @tmp = map { $^char.ord if $^char eq @ascii.any }, "wall".comb;