【问题标题】:Perl - Parsing Arguments/Options with REGEXPerl - 使用 REGEX 解析参数/选项
【发布时间】:2012-11-17 13:31:25
【问题描述】:

我正在创建一个 perl 脚本来转换模板文件 () 中的命令列表,并将它们输出到输出文件 () 中不同格式的另一个文件。

模板文件中的命令如下所示:

command1 --max-size=2M --type="some value"

我在从该字符串中提取选项和值时遇到了一些问题。到目前为止,我有:

m/(\s--\w*=)/ig

哪个会返回:

" --max-size="
" --type="

但是我不知道如何将选项和值作为单独的变量返回,或者如何适应引号的使用。

谁能指引我正确的方向?

旁注:我知道 Getops 在从命令行执行此操作方面做得非常出色,但不幸的是,这些命令是作为字符串传递的 :(

【问题讨论】:

    标签: regex perl parsing arguments


    【解决方案1】:

    Getopt::StdGetopt::Long?

    您看过this 选项还是this 一个?

    似乎没有理由重新发明轮子。

    【讨论】:

    • 谢谢你们的帮助。我应该更彻底地准备好 getops 文档,因为我完全忽略了从字符串传递选项的选项。这是我追求的理想选择。
    【解决方案2】:

    下面的代码产生

    @args = ('command1', '--max-size=2M', '--type=some value');
    

    那适合传递给GetOptions如下:

    local @ARGV = @args;
    GetOptions(...) or die;
    

    最后是代码:

    for ($cmd) {
       my @args;
       while (1) {
          last if /\G \s* \z /xgc;
    
          /\G \s* /xgc;
    
          my $arg;
          while (1) {
             if (/\G ([^\\"'\s]) /xgc) {
                $arg .= $1;
             }
             elsif (/\G \\ /xgc) {
                /\G (.) /sxgc
                   or die "Incomplete escape";
    
                $arg .= $1;
             }
             elsif (/\G (?=") /xgc) {
                /\G " ( (?:[^"\\]|\\.)* ) " /sxgc
                   or die "Incomplete double-quoted arging";
    
                my $quoted = $1;
                $quoted =~ s/\\(.)/$1/sg;
    
                $arg .= $quoted;
             }
             elsif (/\G (?=') /xgc) {
                /\G ' ( [^']* ) ' /xgc
                   or die "Incomplete single-quoted arging";
    
                $arg .= $1;
             }
             else {
                last;
             }
          }
    
          push @args, $arg;
       }
    
       @args
          or die "Blank command";
    
       ...
    }
    

    【讨论】:

    • 此解决方案不会按照 OP 的要求将选项与值分开
    • @Ωmega,它不仅将选项与值分开,而且通过实际使用 GetOptions 来执行此操作,它比所有其他给定解决方案做得更好。停止这种骚扰活动。
    • 感谢您的帮助。我最终在这种情况下使用了 GetOpt。
    【解决方案3】:
    use Data::Dumper;
    $_ = 'command1 --max-size=2M a=ignore =ignore --switch --type="some value" --x= --z=1';
    my %args;
    while (/((?<=\s--)[a-z\d-]+)(?:="?|(?=\s))((?<![="])|(?<=")[^"]*(?=")|(?<==)(?!")\S*(?!"))"?(?=\s|$)/ig) {
      $args->{$1} = $2;
    }
    print Dumper($args);
    
    ---
    
    $VAR1 = {
              'switch' => '',
              'x' => '',
              'type' => 'some value',
              'z' => '1',
              'max-size' => '2M'
            };
    

    (测试这个演示here

    【讨论】:

    • 感谢您的帮助。这也帮助我更好地理解 REGEX。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-12
    • 2021-04-29
    • 2014-06-07
    • 1970-01-01
    • 2011-08-15
    • 1970-01-01
    • 2013-03-06
    相关资源
    最近更新 更多