2010-10-06 5 views
5

Я не знаю ни малейшего количества Perl и исправляю ошибку в скрипте Perl.В Perl, как я могу заменить только первый символ строки?

Учитывая переменную $myvar, которая содержит строку, если первый символ является точкой, замените его на «foo/bar».

Как это сделать?
(Бонусные баллы, если вы можете догадаться ошибку)

+0

Guess, что ошибка? – Benoit

+1

Угадайте ошибку, это исправление, которое вы описываете достаточно? Что делать, если строка начинается с «../»? – Thilo

+0

@Benoit: ошибка, которую я исправляю. @Thilo: не бывает в моем случае (насколько я знаю), но вы правы, у этого есть потенциал для другой ошибки. – Cephalopod

ответ

9
$myvar =~ s+^\.+foo/bar+ ; 
+4

+ являются альтернативными символами кавычки регулярных выражений, потому что нормальный«/»конфликтует с« foo/bar ». что вы там хотите, я лично нахожу скобки более читаемыми: s {^ \.} {foo/bar}. – Thilo

+0

это заменяет все точки или только первый? – Cephalopod

+2

Только тот, который находится в самом начале строки (это это то, что делает ^) – Thilo

5

Некоторые substr магии:

$_ eq '.' and $_ = "foo/bar" for substr $myvar, 0, 1; 

И этот синтаксис заставляет меня любить PERL 5,12

for(substr($myvar, 0, 1)) { 
    when('.') { $_ = "foo/bar" } 
} 
+0

O.o Мне действительно нужно изучить perl ... – Cephalopod

+0

Хорошая и творческая комбинация lvalue substr, aliasing и smart-matching. Мне это нравится! (и все же использовал бы очевидную и удобную для понимания замену регулярного выражения) :-) – rafl

+3

Или, альтернативно, пример всего, что не так с Perl. «For» - для циклизации. Если для использования каких-либо других полезных свойств вам нужно использовать «для», даже если вы не зацикливаете, тогда язык сломан. –

8

Вы можете использовать substr:

substr($myvar, 0, 1, "foo/bar") if "." eq substr($myvar, 0, 1); 
+0

+1 для удобства чтения. Уместно, единственный пример, который не понимал бы сторонник. – Cephalopod

+1

@ Арьян: Я так не думаю. Использование substr на LHS присваивания также чрезвычайно Perlish ... – Thilo

+0

Да, это необычно (для программистов других языков), но намерение совершенно ясно. – Cephalopod

2

Вдохновленный обсуждением ответа @ eugene, вот несколько микро-тестов с использованием ActiveState perl 5.10.1 в Windows XP. Конечно, my benchmarks suck, так что возьмите его с ложкой соли.

#!/usr/bin/perl 

use strict; use warnings; 

use Benchmark qw(cmpthese); 

my $x = 'x' x 100; 
my $y = '.' . $x; 

for my $s ($x, $y) { 
    printf "%33.33s ...\n\n", $s; 
    cmpthese -5, { 
     's///' => sub { 
      my $z = $s; 
      $z =~ s{^\.}{foo/bar}; 
     }, 
     'index/substr' => sub { 
      my $z = $s; 
      if (0 == index $z, '.') { 
       substr($z, 0, 1, 'foo/bar'); 
      } 
     }, 
     'substr/substr' => sub { 
      my $z = $s; 
      if ('.' eq substr $z, 0, 1) { 
       substr($z, 0, 1, 'foo/bar'); 
      } 
     }, 
    }; 
    print '=' x 40, "\n"; 
} 

Выход:

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ... 

        Rate index/substr substr/substr   s/// 
index/substr 1622404/s   --   -14%   -42% 
substr/substr 1890621/s   17%   --   -32% 
s///   2798715/s   73%   48%   -- 
======================================== 

.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ... 

        Rate   s/// substr/substr index/substr 
s///   367767/s   --   -57%   -62% 
substr/substr 857083/s   133%   --   -10% 
index/substr 956428/s   160%   12%   -- 
========================================
Смежные вопросы