首页 新闻 会员 周边 捐助

perl正则模式中可以使用变量替换,为什么还用qr对象

0
[已关闭问题] 关闭于 2025-08-01 14:38

$str="hello worlds fapeche";
$pattern="w.*d";
$str =~ /$pattern/;
print "$&\n";
为什么还用:
$str="hello worlds gaoxiaofang";

直接作为正则表达式

$str =~ qr/w.*d/;
print "$&\n";

保存为变量,再作为正则表达式

$pattern=qr/w.*d/;
$str =~ $pattern; # (1)
$str =~ /$pattern/; # (2)
print "$&\n";

_java_python的主页 _java_python | 小虾三级 | 园豆:984
提问于:2025-08-01 14:34
< >
分享
所有回答(1)
0

先把 3 件事分清,就不会搞混了:
纯字符串当正则
perl
复制
$pattern = "w.d"; # 只是一个普通字符串
$str =~ /$pattern/; # 运行时才把字符串编译成正则
每次匹配都会重新编译,效率低,且如果字符串里有 / 或元字符需要先 quotemeta。
qr// 预编译正则对象
perl
复制
$pattern = qr/w.
d/; # 编译一次,得到 Regexp 对象
$str =~ $pattern; # (1) 直接拿对象用,推荐写法
$str =~ /$pattern/; # (2) 把对象再塞到 // 里,多此一举
(1) 高效;(2) 仍然能跑,但多了一层无谓的包裹。
qr// 内嵌写法
perl
复制
$str =~ qr/w.d/; # 立即匹配,相当于 /w.d/
──────────────────
一句话记忆
字符串 = 模板,每次现编;
qr// 变量 = 预编译好的“正则对象”,直接贴上去用就行。
复制
分享
编译好的正则对象,是啥意思,意思已经通过编译器编译成立字节码了?后面使用的时候直接那字节码去比较?
编辑
复制
可以这么理解,但细节稍不同:
“编译” 在 Perl 里指 正则引擎把模式解析成内部 OP 码树(不是 CPU 字节码),
这一步包括:
词法分析(把 w.*d 拆成原子、量词)
构建 NFA/DFA 状态机
优化(消除冗余分支、贪心/非贪心转换、重复串折叠等)
qr// 变量 里保存的就是这棵 已优化好的 OP 码树,
真正匹配时引擎直接跑这棵树,跳过解析+优化阶段,所以比每次重新 /string/ 快。
它不是机器字节码,而是 Perl 正则引擎私有的中间表示;
跨进程就失效,重启脚本需重新编译。
一句话:
qr// 把正则提前 “翻译”成引擎内部指令表,后面直接执行这张表,省去重复解析。

_java_python | 园豆:984 (小虾三级) | 2025-08-01 14:38
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册