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:如何从预编译版本中获取原始正则表达式?的主要内容,如果未能解决你的问题,请参考以下文章

在 Perl 正则表达式中展开环境变量

在 perl 中编译正则表达式时出现“reg_node overrun”

老男孩带你了解perl正则表达式中的零宽断言

如何分析 Perl 正则表达式?

老男孩带你了解perl正则表达式中的零宽断言

我必须在 Perl 预编译的正则表达式中转义哪些字符?