perl - 如何使用 Perl 以单一方式查找多个正则表达式模式
问题描述
问题更新
我有(更多)正则表达式模式的列表,例如:(注意:序列非常重要)
([a-z]+)(\d+)
\}([a-z]+)
([a-z]+)(\+|\-)
([0-9])\](\+|\-)
...
...
我的输入文件如:
\ce{CO2}
\ce{2CO}
\ce{H2O}
\ce{Sb2O3}
...
...
在我的代码中,我发现了每一个正则表达式模式,比如
if($string=~m/([a-z]+)(\d+)/g) { my statements ... }
if($string=~m/\}([a-z]+)/g) { my statements ... }
if($string=~m/([a-z]+)(\+|\-)/g) { my statements ... }
if($string=~m/([0-9])\](\+|\-)/g) { my statements ... }
除了做上面的代码,还有其他方法可以简化代码吗?
有人可以分享您对我改进以更好地编码的想法。
解决方案
免责声明:您的问题很难阅读,所以这几乎是猜测。我不确定我是否理解你想要做什么。
当您以动态方式处理数据时,一种典型的方法是使用调度表。我们可以在这里做类似的事情。通常使用散列或散列引用,但由于我们需要特定的顺序,我将使用数组代替。
my @dispatch = (
{
pattern => qr/f(o)(o)/,
callback => sub {
my ($one, $two) = @_;
print "Found $one and $two\n";
},
},
{
pattern => qr/(bar)/,
callback => sub {
my $capture = shift;
print "Saw $capture";
},
},
);
这基本上是搜索模式和相关说明的列表。每个模式都有一个回调,它是一个代码引用。我认为传递捕获变量是有意义的,因为您的模式具有捕获组。
现在为了调用它们,我们遍历调度数组,匹配模式,然后调用相关的回调,传入所有的捕获。
my $text = "Foo bar foo bar baz.";
foreach my $search (@dispatch) {
if ($text =~ $search->{pattern}) {
$search->{callback}->(@{^CAPTURE}); # this requires Perl 5.26
}
}
请注意,我正在使用@{^CAPTURE}
5.25.7 中添加到 Perl 中的 .,因此您至少需要稳定的 Perl 5.26 版本才能使用它。(在较旧的 Perl 上,my @capture = $t =~ $search->{pattern}
行为$search->{callback}->(@capture)
类似)。
这比有一个if () {}
语句列表更优雅,因为它很容易扩展。调度表可以根据一些输入动态创建,或者完全从磁盘读取。
当我们运行此代码时,它会创建以下输出
Found o and o
Saw bar
这不是很壮观,但您应该能够使其适应您的模式。另一方面,我不知道您实际上要做什么。如果您想修改字符串而不是仅仅匹配,您可能需要额外的回调参数。
如果您想了解更多关于调度表的信息,我建议您阅读Mark Jason Dominus 的优秀著作Higher Order Perl的第二章,该书在他的网站上以 PDF 格式免费提供。
推荐阅读
- javascript - 动态设置具有角度反应形式的输入占位符
- javascript - 节点 v8 因弱对象而去优化
- python - Paramiko stdout.readlines() 太慢了
- python-3.x - 如何从 RQ 作业中连接到 flask-sqlalchemy 数据库
- typescript - 如何使它成为可扩展的打字稿类型?
- javascript - Javascript / HTML在鼠标单击时将图像添加到中心位置
- php - Laravel Eloquent 多对多不保存密钥
- python - 在提供正确的答复后,我试图阻止这个 if-elif 提出进一步的问题
- javascript - ( Html2Canvas & jsPDF ) 为什么用 chrome 剪切图像?(在 safari 中不会被切断。)
- amazon-web-services - 有没有办法将文件大小作为输入参数从 AWS S3 存储桶传递到 StepFunctions 状态机?