2015-04-14 2 views
2

Я пытаюсь совместить обратную косую черту с последующим символом выхода, например t, n, r, или \ .. как в строке JSON. Для упрощения рассмотрим только \t и \\ .. Например:Матч обратной косой черты с последующим символом эвакуации

use feature qw(say); 
use strict; 
use warnings; 
use Data::Dump qw(dump); 

my @data = (
    [q{\t}, qr/\\t/],   #ok 
    ["\\",  qr/\\/],    #ok 
    ["\\",  qr/[\\]/],   #ok 
    ["\t",  qr/\t/],    #ok 
    ["\t",  qr/[\t]/],   #ok 
    [q{\\\t}, qr/(\\[\\\t])*/], #not ok 
    [q{\\\t}, qr/(\\\\[\\\\t])*/ ],#ok 
); 

for my $i (0..$#data) { 
    my ($str, $regex) = @{$data[$i]}; 
    my $match_result = ($str =~ /^$regex$/) ? "ok" : "not ok"; 
    say(
     "$i : " 
     . dump($str) 
     . ' =~ ' 
     . dump($regex) 
     . ' : ' 
     . $match_result 
    ); 
} 

Выход:

0 : "\\t" =~ qr/\\t/ : ok 
1 : "\\" =~ qr/\\/ : ok 
2 : "\\" =~ qr/[\\]/ : ok 
3 : "\t" =~ qr/\t/ : ok 
4 : "\t" =~ qr/[\t]/ : ok 
5 : "\\\\t" =~ qr/(\\[\\\t])*/ : not ok 
6 : "\\\\t" =~ qr/(\\\\[\\\\t])*/ : ok 

Вопрос заключается в том, почему тест # 5 терпят неудачу. Я бы подумал, что это будет правильное регулярное выражение. Что мне здесь не хватает?

ответ

3

Пункт 5 является

q{\\\t} =~ qr/(\\[\\\t])*/ 

q{\\\t}, что эквивалентно '\\\t'. В одном кавычках нет необходимости, чтобы избежать ничего, кроме

  • разделитель символов
  • обратная косая черта непосредственно перед закрывающим разделителем или другой обратной косой черты

также, любое вхождение двух обратных косых черт вместе берется как сбежавшая обратная косая черта.

So '\\\t' представляет собой трехсимвольную строку, содержащую \\t.

Содержание qr// ведет себя как двойной кавычки контекста, так все обратные косые должны быть экранированы, и может изменить следующий символ.

"(\\[\\\t])*" это восемь-символьная строка, состоящая из (\[\\t])* где \t является "\x09" - символ табуляции. Таким образом, ваш шаблон будет соответствовать строке, состоящей из обратной косой черты, за которой следует вкладка или обратная косая черта, все повторяющиеся ноль или более раз. В строке есть только обратные косые черты и t, поэтому они не могут совпадать.

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

+0

Спасибо за приятное разъяснение! Есть, по крайней мере, две вещи, которые я пропустил. Во-первых, двойная обратная косая черта в 'q' считается единственной обратной косой чертой. Таким образом, семь аргументов chararacter для 'q {\\\\\\ t}', становятся строкой длиной 4 символа. Во-вторых, как вы указали, '' t 'становится' \ x09' внутри 'qr'. То, что я хотел сделать для теста № 5, было, вероятно, «[q {\\\\\\ t}, qr/(\\ [t \\]) * /]' –

+3

@ HåkonHægland: похоже, что вы схватил его. Многие не понимают, что в одинарных кавычках * одиночные * обратные косые черты сохраняются и не нуждаются в удвоении. Это означает, что пути Windows, такие как «C: \ Windows \ System32 \ drivers», прекрасны. Единственная проблема возникает, когда вам нужна скрытая обратная косая черта, которая * * должна быть экранирована, или UNC-путь, такой как '\\ SERVER \ backup \ 20150415', должен быть выражен как' \\\ SERVER \ backup \ 20150415 ' '. (На самом деле там нужны только три обратной косой черты, но четыре кажутся лучше.) – Borodin

1

Причина заключается в следующем:

q{\\\t} 

является

"\\\\t" 

, который 3-х символов, 2 обратных слэша с 'т'

Регулярное выражение # 5 Соответствуют arbritray количество пар символов (a \ затем еще один или табулятор <)

изменение это

[q{\\\t}, qr/(\\[\\\t]*)*/], #not ok 

все равно будет не в порядке,

но

[q{\\\t}, qr/(\\[\\t]*)*/], #ok 

будет работать.

НТН Georg

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