如何在Raku中向MAIN传递正则表达式?(含代码问题咨询)
在Raku中向MAIN传递正则表达式的惯用写法
你的代码确实能实现需求,但存在你提到的两个问题,下面是更符合Raku惯用风格的解决方案:
一、避免修改默认Str类的方案
不需要通过MONKEY-TYPING增强Str类,直接在MAIN中接收字符串参数并转换为正则表达式即可,这样不会产生全局副作用:
#!/bin/raku sub MAIN(Str $pattern) { # 将命令行传入的字符串转换为正则表达式 my $regex = rx/ <$pattern> /; if "hello world" ~~ $regex { say "hello world"; } }
运行示例
# 带引号传递正则(推荐) ./cliRegex.raku '.*' hello world # 匹配特定单词 ./cliRegex.raku 'world' hello world
二、解决正则表达式传递异常的问题
你遇到的./cliRegex.raku .*报错,本质是shell的通配符扩展行为:当你不带引号输入.*时,bash等shell会自动将其替换为当前目录下的所有隐藏文件和普通文件,导致MAIN收到多个参数,不符合预期的单个参数要求,因此触发Usage提示。
解决方法:
- 始终用单引号或双引号将正则表达式括起来,避免shell解析通配符;
- 如果需要在正则中使用shell变量,可以用双引号,但注意转义特殊字符;
- 临时关闭shell的通配符扩展(如bash中执行
set -f),但不推荐,因为会影响后续命令。
更地道的类型转换写法(可选)
如果你希望保持MAIN参数的Regex类型,可以使用自定义类型强制转换,而不是修改全局Str类:
#!/bin/raku # 定义从Str到Regex的强制转换逻辑 multi sub coerce(Str $str, ::(Regex)) { rx/ <$str> / } sub MAIN(Regex() $pattern) { if "hello world" ~~ $pattern { say "hello world"; } }
这种写法既保留了参数类型的清晰性,又不会污染全局Str类的方法。
内容的提问来源于stack exchange,提问作者mikeLundquist
相关产品推荐
相关产品推荐

