2009-12-12 3 views
4
$stuff = "d:/learning/perl/tmp.txt"; 

open STUFF, $stuff or die "Cannot open $stuff for read :$!"; 
while (<STUFF>) { 
    my($line) = $_; # Good practice to always strip the trailing 
    chomp($line); 
    my @values = split(' ', $line); 

    foreach my $val (@values) { 

     if ($val == 1){ 
      print "1 found";  
     } 
     elsif ($val =~ /hello/){ 
      print "hello found";  
     } 
     elsif ($val =~ /"/*"/){ # I don't know how to handle here. 
      print "/* found";  
     } 
     print "\n"; 
    } 
} 

Мои tmp.txt:Как совместить «/ *» в регулярном выражении?

/* CheerStone ColdStunner 

1 Cheer Rock 

hello Boo Pedigree 

Как обрабатывать последовательность символов /* в моем коде?

+1

Спасибо отметил, но название вопроса лучше свободны от неродственных комментариев. – pavium

+7

Поскольку вы пытаетесь изучить Perl, вот несколько рекомендаций по стилю: во-первых, используйте три формы аргументов 'open':' open my $ fh, '<', $ filename', чтобы избежать любых неожиданностей, если '$ filename' начинается с специальные символы. Во-вторых, используйте лексические дескрипторы файлов, как показано выше. Файлы с файлами в формате Bareword представляют собой пакетный охват, а глобальные переменные затрудняют отслеживание проблем. В-третьих, назначьте ввод немедленно переменной, а не выполните ее в два этапа: 'while (my $ line = <$fh>) {chomp $ line; ...} ' –

+0

Возможный дубликат [Как обрабатывать специальные символы в регулярном выражении Perl?] (Http://stackoverflow.com/questions/576435/how-do-i-handle-special-characters-in-a -perl-regex) – daxim

ответ

8

Оба персонажа имеют особое значение в регулярном выражении Perl, поэтому вы должны их избежать с помощью обратной косой черты:

$val =~ /\/\*/ 

Btw, вы, вероятно, следует добавить ^ перед всеми регулярными выражениями, потому что вы, кажется, хотят для обработки только текста в начале строки.

+1

Привет, Лукас, большое вам спасибо. –

+2

Старайтесь избегать «пикетирования» для лучшей читаемости кода. –

16

* - специальный символ. Таким образом, вы должны избавиться от нее:

m{/\*} 

Как Adam Bellaire предложил, вот краткое объяснение:

Пикет-ограждения лучше избегать. Для этого иногда должны использоваться разделители, отличные от /. m должен предшествовать первому разделителю при использовании таких разделителей. Если в качестве первого разделителя используется какой-либо из скобок, в качестве ограничителя конца следует использовать соответствующую закрывающую скобу.

+3

Вы также использовали разделитель, отличный от //, с оператором сопряжения, который абсолютно подходит, но вы должны объяснить это в своем ответе. Я не думаю, что ОП знает, что вы можете это сделать. –

+2

Это не просто OP ... Есть много людей, использующих Perl, которые не знают, что вы можете это сделать. –

12

Существуют различные способы метасимволов метаданных без мета. В вашем случае вам нужно обработать символ, который является разделителем по умолчанию, а также метасимволом.

  • В случае символа-ограничителя, который вы хотите быть буквенный символ, вы можете избежать этого персонажа с \, хотя вы можете получить leaning toothpick syndrome:

    m/\/usr\/local\/perls/; 
    
  • Вы можете изменить разделитель :

    m(/usr/local/perl); 
    
  • Вы можете избежать мета-символы таким же образом:

    m(/usr/local/perl\*); 
    
  • Если вы хотите часть вашего шаблона, чтобы быть только буквальные символы, вы можете использовать \Q автоматически избежать их для вас:

    m(\Q/usr/local/perl*); 
    
  • Если вы хотите меньшую часть вашего рисунка будет только буквальные символы, вы можете использовать \Q затем выключить его \E:

    m(/usr/local/perl\Q*+?\E/); 
    
  • \Q действительно то же самое, что и quotemeta. Положив шаблон в переменную, то интерполяционный его в операторе сопоставления также решает проблему разделителей:

    my $pattern = quotemeta('/usr/local/perl*+?/'); 
    m/$pattern/; 
    
+0

'\ Q' именно то, что я искал: спасибо! – smithfarm

Смежные вопросы