Как вставить переменную в пользовательский класс символов?

Я пытаюсь разрешить программам определять класс символов в зависимости от встречающегося текста. Однако ‹[]> воспринимает символы буквально, и следующее приводит к ошибке:

my $all1Line = slurp "htmlFile";
my @a = ($all1Line ~~ m:g/ (\" || \') ~ $0 {} :my $marker = $0; http <-[ $marker ]>*? page <-[ $marker ]>*? /); # error: $marker is taken literally as $ m a r k e r

Я хотел сопоставить все ссылки в формате "https://foo?page=0?ssl=1" или "http... страница..."


person lisprogtor    schedule 25.10.2019    source источник


Ответы (1)


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

my $input = "(abc)aaaaaa(def)ddee(ghi)gihgih(jkl)mnmnoo";

my @output = $input ~~ m:g/
    :my @valid;                # initialize variable in regex scope
    '(' ~ ')'  $<valid>=(.*?)  # capture initial text
    { @valid = $<valid>.comb } # split the text into characters
    $<text>=(@valid+)          # capture text, so long as it contains the characters
/;

say @output;
.say for @output.map(*<text>.Str);

Выход которого

[「(abc)aaaaaa」
 valid => 「abc」
 text => 「aaaaaa」 「(def)ddee」
 valid => 「def」
 text => 「ddee」 「(ghi)gihgih」
 valid => 「ghi」
 text => 「gihgih」]
aaaaaa
ddee
gihgih

В качестве альтернативы вы можете сохранить все определение класса символов в переменной и ссылаться на переменную как <$marker-char-class>, или, если вы хотите избежать этого, вы можете определить все это как встроенный код, который будет интерпретироваться как регулярное выражение с <{ '<[' ~ $marker ~ ']>' }>. Обратите внимание, что оба метода подвержены одной и той же проблеме: вы конструируете класс символов на основе синтаксиса регулярных выражений, что может потребовать escape-символов или определенного порядка, что определенно неоптимально.

Если это то, что вы будете делать очень часто и не очень специально, вы также можете определить свой собственный токен метода регулярного выражения, но это, вероятно, очень излишне и лучше послужит отдельным вопросом.

person user0721090601    schedule 26.10.2019
comment
Большой! Большое спасибо пользователю 0721090601. Это был очень умный способ использовать регулярное выражение! Спасибо !!! - person lisprogtor; 27.10.2019