Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 如何将正则表达式字符串替换值($1、$2等)映射到散列?_Regex_Perl_Hash_Map - Fatal编程技术网

Regex 如何将正则表达式字符串替换值($1、$2等)映射到散列?

Regex 如何将正则表达式字符串替换值($1、$2等)映射到散列?,regex,perl,hash,map,Regex,Perl,Hash,Map,应该匹配这样的字符串 my (@keys,@values) = ($text =~ /\{IS\:([a-zA-Z0-9_-]+)\}(.*)\{\\IS\:([a-zA-Z0-9_-]+)\}/g); 这很好,除了所有$1、$2和$3的值都被转储到@keys中。。所以我想弄清楚如何让这些家伙进入一个1=>2美元对的好散列 对于完整上下文,我真正想做的是让regex表达式返回一个如下的数据结构(并附加一个键被找到的次数计数) 有没有一种方法可以使用map{}函数通过正则表达式来实现这一点?也许

应该匹配这样的字符串

my (@keys,@values) = ($text =~ /\{IS\:([a-zA-Z0-9_-]+)\}(.*)\{\\IS\:([a-zA-Z0-9_-]+)\}/g);
这很好,除了所有$1、$2和$3的值都被转储到@keys中。。所以我想弄清楚如何让这些家伙进入一个1=>2美元对的好散列

对于完整上下文,我真正想做的是让regex表达式返回一个如下的数据结构(并附加一个键被找到的次数计数)

有没有一种方法可以使用map{}函数通过正则表达式来实现这一点?也许是这样的

{ 
  cow_1 => moo,
  cow_2 => moo,
  dog_1 => bark,
  dog_2 => meow,
}
$1等于$3以确保它是一个匹配的标记(不需要递归检查这些标记是否嵌套),如果是,则使用$1作为键,使用$2作为值

然后,对于这些key=>value对中的每一个,我想替换

my %datahash = map { ( $1 eq $3 ) ? { $1 => $2 } : undef } @{ regex...};

然后,如果$cachedData{cow}为true,则所有cow_*将替换为其在%datahash中的密钥

{cow_1}
{cow_2}

/x
为可读性添加了修饰符)

我从正则表达式中删除了无用的反斜杠和paren,并在char类中使用了快捷键:

$hash{$1} = $2 while 
        $text =~ /\{IS\:([a-zA-Z0-9_-]+)\}
                           (.*)
                  \{\\IS\:([a-zA-Z0-9_-]+)\}/gx;
  • $dataHash{cow}[$num]
    完全等同于
    $dataHash{“cow{$num”}
  • 使用$dataHash{cow}以及,相对于 使用“扫描”键
    #!/usr/bin/perl
    use warnings;
    use strict;
    
    my $text = '{IS:cow}moo{\IS:cow}
    {IS:cow}moo{\IS:cow}    
    {IS:dog}bark{\IS:dog}
    {IS:dog}meow{\IS:dog}';
    
    my %cnt;
    my %animals;
    while ( $text =~ /\{IS:([\w-]+)}(.*)\{\\IS:[\w-]+}/g ){
        $animals{$1 . '_' . ++$cnt{$1}} = $2;
    }
    
    print "$_ => $animals{$_}\n" for sort keys %animals;
    
    使用该习惯用法,您可以创建一个散列,类似于您想要的:

    sub multi_hash {
        use List::Pairwise qw<mapp>;
        my %h;
        mapp { push @{ $h{ $a } }, $b } @_;
        return wantarray ? %h : \%h;
    }
    
    这给了我:

    my %dataHash 
        = multi_hash(  map { m/[{]IS:([\w-]+)[}]([^{]+)[{]\\IS:\1[}]/ } @lines )
        ;
    

    这很好,/x修饰符做了什么?@nodebunny它忽略了空格,因此允许您很好地格式化正则表达式。如果您想确保开始/结束标记匹配,那么在正则表达式中使用backref:/\{is:([\w-]+)}(.*)\{\\is:\1}/g进行此操作 @dataHash{ grep { m/^cow_/ } keys %dataHash }
    sub multi_hash {
        use List::Pairwise qw<mapp>;
        my %h;
        mapp { push @{ $h{ $a } }, $b } @_;
        return wantarray ? %h : \%h;
    }
    
    my %dataHash 
        = multi_hash(  map { m/[{]IS:([\w-]+)[}]([^{]+)[{]\\IS:\1[}]/ } @lines )
        ;
    
    %dataHash: {
                 cow => [
                          'moo',
                          'moo'
                        ],
                 dog => [
                          'bark',
                          'meow'
                        ]
               }