如何从模块导出正则表达式



我有一个regex,我想从我的模块中导出,代码如下:

package regExport;
use strict;
use warnings;
use Exporter qw(import);
our @EXPORT_OK = qw(re);
my re = /.../; # my regex is here

它被进口到这里

use regExport qw(re);
my @li = ("man", "qwrt", "mnbv", "azx", "aeiou");
foreach my $st (@li) {
$li =~ a/b/; # I wish to test my regex on each of these strings
}

任何人都知道我该怎么做。我觉得很困惑该怎么做。

最简单但不是最好的方法(见下文(是生成一个带有模式的变量。最好使用qr运算符,然后可以导出变量

package RegExport;
use strict;
use warnings;
use Exporter qw(import);
our @EXPORT_OK = qw($re_pattern);
our $re_pattern = qr/(w+)/i;  # capture a "word" case-insensitive
1;

请注意,根据Pascal大小写的常用Perl约定,我已经将包名称大写。(然后文件名需要跟在后面,并且是RegExport.pm。(

然后将其用作

use warnings;
use strict;
use feature 'say';
use FindBin qw($RealBin);
use lib $RealBin;
use RegExport qw($re_pattern);
my $text = q(Some text with a bunch of words. In sentences.);
while ($text =~ /$re_pattern/g) { 
say "Word: $1";
}

在这里,我希望RegExport.pm与程序位于同一目录中。使用$RealBin是一种很好的方法,可以在包含库的搜索路径中添加一个相对于程序本身所在位置的目录(在这种情况下,是程序的目录(。

如果你真的想使用这样的变量(但请继续阅读!(,那么就不需要从它的包中导出它,而是可以在调用方中使用它的完全限定名称

use RegExport;
... $RegExport::re_pattern ...

这有时是在库中为各种设置所做的。

然而,在什么不导出一节中,文档对此有一些说明

Donot导出变量名。

@EXPORT_OK = qw($svar @avar %hvar); # DON'T!

导出变量不是一个好主意。它们可以在引擎盖下发生变化,在远处引发难以追踪和修复的可怕影响。相信我:它们不值得。

这个好建议在图书馆中偶尔会被违反,效果很好;一个例子是上面使用的CCD_ 3。但是,如果你没有压倒一切的原因,那么最好遵循它——并使用一个函数返回值

package RegExport;
use strict;
use warnings;
use Exporter qw(import);
our @EXPORT_OK = qw(get_pattern);
sub get_pattern {
my @specs = @_;  # any input on how to form the pattern
my $re_pattern = qr{...};
return $re_pattern;
}
1;

现在你用它作为

use RegExport qw(get_pattern);
my $re = get_pattern();   # or pass extra rules for how to form it

并使用正则表达式中的CCD_ 4作为就绪模式。

现在,这段代码的用户和未来的代码维护人员都很高兴。

你很接近。你的代码只有几个问题:

  • 要导出到另一个包(即main(的变量需要声明为包变量(使用our(,而不是词法变量(使用my(
  • 您调用的是匹配运算符(/ ... /(,而不是声明和创建正则表达式。您需要qr/ ... /
  • 虽然您加载了Exporter,但为了使用import(),您还需要使类成为一个子类
  • 您的程序包最后需要返回一个真实值

所以我在模块中有这个:

package RegExport;
use strict;
use warnings;
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw($re);
our $re = qr/[aeiou]/; # my regex is here

1;

这个在测试程序中:

use lib '.';
use feature 'say';
use RegExport;
my @li = ("man", "qwrt", "mnbv", "azx", "aeiou");

foreach my $st (@li) {
if ($st =~ /$re/) {
say "Match: $st";
} else {
say "No match: $st";
}
}

请注意,我已将您的包裹名称更改为RegExport。Perl中的传统是,标准的用户定义模块以大写字母开头。

最新更新