perl:如何从预编译版本中获取原始正则表达式?
Posted
技术标签:
【中文标题】perl:如何从预编译版本中获取原始正则表达式?【英文标题】:perl: how to get the original regex from the precompiled version? 【发布时间】:2011-11-30 18:06:06 【问题描述】:简单代码:
use 5.014;
use warnings;
my $re = <DATA>;
chomp $re;
my $re2 = qr/$re/;
say $re2;
__END__
^\w$
结果:
(?^u:^\w$) #added the (?^u:
是否有任何正确的方法来反编译 $re2 以获取原始正则表达式?
动机:正则表达式是一个配置值,所以需要:
阅读 编译它 将其保存到文件中以备后用。但是不能保存编译后的正则表达式以供以后使用,因为在每次编译时,正则表达式都会用 (?^u: 扩展,所以经过几个循环后,我以 like 结尾:
(?^u:(?^u:(?^u:(?^u:(?^u:^\w$)))))
因此问题是:
这里有什么正确的方法吗,编译后的版本怎么保存? 如果没有办法 - 如何反编译,获取原始版本? 有什么想法吗?【问题讨论】:
你说你从文件中读取了模式,所以你有你想要保存到文件中的东西,那你为什么不保存呢? 【参考方案1】:虽然我只是保留字符串副本以供数据使用,然后在需要使用它时编译一个副本,但您也可以使用核心 re
模块中的 regexp_pattern 函数返回用于返回的模式创建一个编译的正则表达式:
use re 'regexp_pattern';
print regexp_pattern qr/^\w$/;
打印
^\w$
【讨论】:
这正是我所需要的。使用 5.10 以上的 perl - 太好了... ;) 谢谢! 这不是它打印的内容,至少在 5.14 中不是。 @ikegami => 我这里有 5.10.1 正在工作,这正是它打印出来的。此外,它不会因为qr/foo\/bar/
而失败,它只是返回一个不符合那些引用字符的值......
从regexp_pattern上的文档:In list context it returns a two element list, the first element containing the pattern and the second containing the modifiers used when the pattern was compiled.
测试的时候发现上面提到的两个例子打印了一个列表,其中第二个元素是u
。【参考方案2】:
re::regexp_pattern
感谢vpit 在MagNET #perl 上指出这一点。
【讨论】:
刚读过这里是'use re ...'的另一个答案。也感谢达克西姆 - 不幸的是只能接受一个..【参考方案3】:原来是一个运算符,而不是一个正则表达式模式。仅查看regexp_pattern
(模式)返回的第一个值会导致信息丢失。您还需要查看第二个(标志)。
qr/foo/ # pat: foo flags: u
qr/foo/u # pat: foo flags: u
use re '/u'; qr/foo/ # pat: foo flags: u
qr/foo/a # pat: foo flags: a
use re '/a'; qr/foo/ # pat: foo flags: a
qr/foo/i # pat: foo flags: ui
use re '/i'; qr/foo/ # pat: foo flags: ui
use re '/a'; qr/foo/i # pat: foo flags: ai
use re '/ai'; qr/foo/ # pat: foo flags: ai
为了尽可能接近原始运营商,您需要
use re qw( regexp_pattern );
my ($pat, $flags) = regexp_pattern($re);
$pat =~ s/\\/g;
say qqqr/$pat/$flags;
【讨论】:
我正在编译没有标志的正则表达式,所以 Erics 简单版本对我来说就足够了。无论如何,非常感谢您的详细解释!!! @jm666,同样,如果你知道,为什么需要从 re 中提取原始模式?【参考方案4】:也许很简单:
...
($reoriginal = $re2) =~ s^\(\?.+:(.+)\)$1;
say $reoriginal
【讨论】:
当心,版本不一致:***.com/q/8082617#comment-10190574以上是关于perl:如何从预编译版本中获取原始正则表达式?的主要内容,如果未能解决你的问题,请参考以下文章