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

How to export a regex from a module

我有一个正则表达式,我想从我的模块中导出,代码如下:

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 operator,然后可以导出变量

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;

请注意,根据 Perl 的 Pascal 大小写惯例,我将包名称大写了。 (那么文件名需要跟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: ";
}

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

如果您真的想使用这样的变量(请继续阅读!),则无需将其从包中导出,但可以在调用者中使用其完全限定名称

use RegExport;

... $RegExport::re_pattern ...

这是图书馆有时针对各种设置所做的。

但是,文档在 What not to export

部分对此有一些说明

Do not export variable names.

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

Exporting variables is not a good idea. They can change under the hood, provoking horrible effects at-a-distance that are too hard to track and to fix. Trust me: they are not worth it.

这条好建议在图书馆中偶尔会被违反,效果不错;上面使用的 $RealBin 就是一个例子。但是,如果您没有压倒一切的理由,那么最好遵循它——并使用一个函数来 return 值

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

并在正则表达式中使用 $re 作为现成模式。

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

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

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

所以我在模块中有这个:

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 的传统。