【问题标题】:evaluating a user-defined regex from STDIN in Perl在 Perl 中从 STDIN 评估用户定义的正则表达式
【发布时间】:2009-07-10 22:28:06
【问题描述】:

我正在尝试用 Perl 制作一个动态模式测试器。 基本上它会要求您输入模式,然后给您一个 >>>> 提示,您可以在其中输入可能的匹配项。如果匹配,则显示“匹配后匹配部分之前的%%%%”,如果不匹配,则显示“%%%!不匹配的字符串”。这样做很简单:

while(<>){
    chomp;
    if(/$pattern/){
        ...
    } else {
        ...
    }
}

但我希望能够输入/sometext/i 这样的模式,而不仅仅是sometext 我想我会为此使用 eval 块?我该怎么做?

【问题讨论】:

  • 也许你应该只使用 Devel::REPL 而不是自己编写。
  • 是为了学习 Perl,不是为了项目
  • 我很困惑:出于练习的目的,为什么不能你只使用/$pattern/i?话虽如此,不要忘记您总是可以通过其他方式解决问题:更改您正在测试的字符串(使其全部高位或全部低位)而不是更改匹配项。这在处理简单的用户输入(捕捉拼写错误)时通常很有用:Q 或 q、Quit、quIt 等。
  • 我是在练习的基础上建立起来的——我并不是希望它一直匹配任何情况,而是我希望能够指定整个来自输入的正则表达式。这是我自己的练习

标签: regex perl


【解决方案1】:

这听起来像是字符串eval 的工作,记住不要评估不受信任的字符串。

#!/usr/bin/perl

use strict;
use warnings;

my $regex = <>;
$regex = eval "qr$regex" or die $@;
while (<>) {
    print  /$regex/ ? "matched" : "didn't match", "\n";
}

这是一个运行示例:

perl x.pl
/foo/i
foo
matched
Foo
matched
bar
didn't match
^C

【讨论】:

  • 你的意思是如果用户传入字符串“s/foo/bar/”?在那种情况下,我会说类似my $subst = &lt;&gt;; while (&lt;&gt;) { eval $subst or die $@; print } 的话,但同样,这非常很危险。用户在第一行输入的任何内容都将作为 Perl 代码执行。
  • 我确实尝试过类似的东西 - 但替换中的模式一直无法匹配任何东西。
【解决方案2】:

你可以写/(?i:&lt;pattern&gt;)/而不是/&lt;pattern&gt;/i

【讨论】:

    【解决方案3】:

    这对我有用:

    my $foo = "My bonnie lies over the ocean";
    
    print "Enter a pattern:\n";
    while (<STDIN>) {
       my $pattern = $_;
       if (not ($pattern =~ /^\/.*\/[a-z]?$/)) {
          print "Invalid pattern\n";
       } else {
          my $x = eval "if (\$foo =~ $pattern) { return 1; } else { return 0; }";
          if ($x == 1) {
             print "Pattern match\n";
          } else {
             print "Not a pattern match\n";
          }
       }
       print "Enter a pattern:\n"
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多