2009-12-15 22 views
6

Tôi muốn làm điều gì đó như thế này: sau đóPerl: Tôi có thể lưu trữ backreferences (không phải giá trị của chúng) trong các biến không?

my $text = "The owls are not what they seem."; 
my $pattern = '(\s+)'; 
my $replacement = '-$1-'; 
$text =~ s/$pattern/$replacement/g; 

$ text nên là: gì- -owls- -are- -not- -what- -they- -seem.

Nhưng tất nhiên nó giống như: The $ 1-owls- $ 1-là- $ 1-not- $ 1-what- $ 1-them- $ 1-dường như.

Tôi đã thử tất cả các loại backreferences ($ 1, \ 1, \ g {1}, \ g1) và tất cả chúng đều không hoạt động . Trình sửa đổi/e không hoạt động. cái này nó có hoàn toàn có thể xảy ra được không?

Mục đích là để thay đổi một số văn bản bên trong một đối tượng với một dòng như thế này: $ object-> replace ('() oo.', '$ 1AR')

Bất kỳ ý tưởng khác thế nào điều này có thể là làm xong?

Cảm ơn bạn rất nhiều.

+0

qr/(\ s +)/là tốt hơn '(\ s +)' –

Trả lời

12

Bạn có thể eval và sau đó mở rộng chuỗi sử dụng /ee:

my $text = "The owls are not what they seem."; 
my $pattern = '(\s+)'; 
my $replacement = q{"-$1-"}; 
$text =~ s/$pattern/$replacement/eeg; 

Từ perldoc perlop:

e Đánh giá phía bên phải như là một biểu.

ee Đánh giá phía bên phải như là một chuỗi sau đó eval kết quả

Tuy nhiên, tôi sẽ cảm thấy an toàn hơn với

my $replacement = sub { "-$1-" }; 
$text =~ s/$pattern/$replacement->()/eg; 

Nhưng tất cả phụ thuộc vào bối cảnh mà bạn đang làm điều này.

+0

ee = Đánh giá rồi mở rộng các biến. –

+2

Tôi có thể nghĩ về tiểu lĩnh vực. Nó hiển nhiên bây giờ. Và nó hoàn toàn phù hợp. Cảm ơn bạn! – wuwuwu

-3

$ text = ~ s/$ pattern/- $ 1-/g;

+0

Không, tôi không thể cung cấp phần '- $ 1-' trực tiếp như điều này. Nó nằm trong một biến: $ replacement = '- $ 1-'; $ text = ~ s/$ pattern/$ replacement/g; – wuwuwu

3

Giải pháp của Sinan Ünür sẽ hoạt động nhưng vẫn yêu cầu chuỗi thay thế phải là chữ bên trong chương trình tại một số thời điểm. Nếu đó là chuỗi thay thế xuất phát từ dữ liệu, bạn sẽ phải làm điều gì đó một chút fancier:

sub dyn_replace { 
    my ($replace) = @_; 
    my @groups; 
    { 
    no strict 'refs'; 
    $groups[$_] = $$_ for 1 .. $#-;  # the size of @- tells us the number of capturing groups 
    } 
    $replace =~ s/\$(\d+)/$groups[$1]/g; 
    return $replace; 
} 

và sau đó sử dụng nó như

$text =~ s/$pattern/dyn_replace($replacement)/eg; 

Lưu ý rằng điều này cũng tránh eval và cho phép sử dụng các bộ điều chỉnh như/g. Mã được lấy từ this Perl Monks node nhưng tôi đã viết nút đó sao cho được ok :)

+0

Theo như tôi hiểu điều này, nó bằng cách nào đó giống như giải pháp subref của Sinan Ünür, ngoại trừ nó phức tạp hơn nhiều. – wuwuwu

+2

Giải pháp của Sinan yêu cầu $ thay thế thành một chuỗi chữ bên trong subref. Của tôi cho phép nó được bất kỳ giá trị chuỗi tùy ý. – Dan

Các vấn đề liên quan