如何在散列中使用s /作为键?

时间:2015-03-19 05:15:05

标签: perl

我有一个hash的define_3,看起来像这样

      'PIOMUX2_UART_3_TXD' => 'CONFIG_PIO31_6_SELECTOR',
      'PIOMUX_UART_1_TXD' => 'CONFIG_PIO22_7_SELECTOR',
      'PIOMUX_UART_11_TXD' => 'CONFIG_PIO0_4_SELECTOR',
      'PIOMUX_UART_10_TXD' => 'CONFIG_PIO0_1_SELECTOR',
      'PIOMUX2_UART_1_TXD' => 'CONFIG_PIO25_2_SELECTOR',
      'PIOMUX_UART_3_TXD' => 'CONFIG_PIO32_6_SELECTOR',

要更改所有键和值的某些部分,我确实这样做了:

  for (values %defines_3)    
{ 
 s/CONFIG_/PIO_M_U_/g; 
 s/_SELECTOR//g;
 }

 for (keys %defines_3)  
{
s/_TXD//g;
}

 print Dumper \%defines_3; 

之后我得到了这个:

      'PIOMUX2_UART_3_TXD' => 'PIO_M_U_PIO31_6',
      'PIOMUX_UART_1_TXD' => 'PIO_M_U_PIO22_7',
      'PIOMUX_UART_11_TXD' => 'PIO_M_U_PIO0_4',
      'PIOMUX_UART_10_TXD' => 'PIO_M_U_PIO0_1',
      'PIOMUX2_UART_1_TXD' => 'PIO_M_U_PIO25_2',
      'PIOMUX_UART_3_TXD' => 'PIO_M_U_PIO32_6',

所以基本上我无法替换键,但是使用s /以我想要的方式替换值。如何更换钥匙?

3 个答案:

答案 0 :(得分:4)

values()正在生成lvaluesforeach别名为$_,因此可以直接更改。必须从哈希中删除keys()才能进行更改

for (keys %defines_3)   {
  my $v = delete $defines_3{$_};
  s/_TXD//g;
  $defines_3{$_} = $v;
}

或支持/r切换的新perl,

for (keys %defines_3)   {
  $defines_3{ s/_TXD//gr } = delete $defines_3{$_};
}

答案 1 :(得分:2)

您无法重命名哈希键,因为它们存储为简单的C字符串而不是Perl标量变量。要获得相同的效果,您可以删除哈希元素并使用新密钥重新插入。

有用的是,delete运算符返回哈希元素的值,所以你可以这样写。

请注意,在迭代时修改散列或数组通常是不明智的,但在这种情况下它是安全的,因为keys %data表达式返回所有散列键的固定列表。与哈希本身分开。

use strict;
use warnings;

my %data = (
  PIOMUX2_UART_3_TXD => 'CONFIG_PIO31_6_SELECTOR',
  PIOMUX_UART_1_TXD  => 'CONFIG_PIO22_7_SELECTOR',
  PIOMUX_UART_11_TXD => 'CONFIG_PIO0_4_SELECTOR',
  PIOMUX_UART_10_TXD => 'CONFIG_PIO0_1_SELECTOR',
  PIOMUX2_UART_1_TXD => 'CONFIG_PIO25_2_SELECTOR',
  PIOMUX_UART_3_TXD  => 'CONFIG_PIO32_6_SELECTOR',
);

for my $key ( keys %data) {
  (my $new_key = $key)               =~ s/_TXD$//;
  (my $new_val = delete $data{$key}) =~ s/^CONFIG_(.+)_SELECTOR$/PIO_M_U_$1/;
  $data{$new_key} = $new_val;
}

use Data::Dump;
dd \%data;

<强>输出

{
  PIOMUX2_UART_1 => "PIO_M_U_PIO25_2",
  PIOMUX2_UART_3 => "PIO_M_U_PIO31_6",
  PIOMUX_UART_1  => "PIO_M_U_PIO22_7",
  PIOMUX_UART_10 => "PIO_M_U_PIO0_1",
  PIOMUX_UART_11 => "PIO_M_U_PIO0_4",
  PIOMUX_UART_3  => "PIO_M_U_PIO32_6",
}

答案 2 :(得分:2)

使用pairmap中的List::Util函数可能最简单。对于输入列表中的每个键/值对,它的块被执行一次,并且收集它返回的任何值列表,就像常规map一样。这样可以很容易地从旧的哈希中构建一个新哈希:

use 5.014;  # for the s///r syntax
use List::Util qw( pairmap );

my %new_hash = pairmap {
   ( $a =~ s/_TXD$//r, $b =~ s/^CONFIG_(.+)_SELECTOR$/PIO_M_U_$1/r )
} %old_hash;

如果你在没有s///r语法的5.14之前被卡住了,你可以用

来做
use List::Util qw( pairmap );

my %new_hash = pairmap {
   my ( $key, $val ) = ( $a, $b );
   $key =~ s/_TXD$//;
   $val =~ s/^CONFIG_(.+)_SELECTOR$/PIO_M_U_$1/;
   ( $key, $val )
} %old_hash;