TR/// : Как применить TR к строке?

С помощью tr/// я могу сделать это:

my $str = 'xABCz';
$str ~~ tr:c/ABC//;

say "-->{$str}<--";

--output:--
-->ABC<--

Но с помощью TR///, который создает новую строку, похоже, нет способа применить его непосредственно к строке:

my $str = 'xABCz';
$str ~~ tr:c/ABC//;

my $new_str = $str ~~ TR:c:d/ABC//;
say "-->{$new_str}<--";

--output:--
-->True<--

Я могу использовать with, чтобы установить $_ на $str:

my $str = 'xABCz';

with $str {   # now $_ refers to $str
    my $new_str = TR:c:d/ABC//;  # TR/// is called on $_.
    say "-->{$new_str}<--";
} 

--output:--
-->ABC<--

...или даже:

my $str = 'xABCz';
my $new_str = TR:c:d/ABC// with $str;

say "-->{$new_str}<--";

--output:--
-->ABC<--

В Perl я бы написал:

my $str = 'xABCz';
my $new_str = $str =~ tr/ABC//rcd;  #r - new_string, c - complement, d - delete
say $new_str;

-output:--
ABC

см. выпуск ракудо №1551.

raiph 01.03.2024 04:56

К вашему сведению, вы можете перезаписать оригинал $str с помощью: $str = TR:c:d/ABC// given $str;.

jubilatious1 01.03.2024 23:38
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
2
128
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Str.trans должен иметь такой же эффект неразрушающим образом.

my $new_str = $str.trans("ABC" => "")

...так что в моем случае: $new_str = $str.trans('ABC' => '', :c, :d);

7stud 01.03.2024 02:01

На самом деле, в этом случае :d не нужен из-за того, что trans() повторяет символы замены, если в совпадении больше символов. Например: 'ABCDE'.trans('ABCD' => 'xy')выходы xyxyE. С другой стороны, добавление опции :d приведет к удалению всех символов совпадения, для которых нет соответствующего символа замены: 'ABCDE'.trans('ABCD' => 'xy', :d) выводит xyE.

7stud 01.03.2024 17:09

Не существует правильного способа использования TR с ~~; TR всегда должен работать с переменной темы (например, устанавливаться с помощью with). TR — это транслитерационный эквивалент S (неразрушающая замена), а в документации для S отмечается, что:

Примечание. Поскольку результат получается как возвращаемое значение, использование этого оператора с оператором ~~ smartmatch является ошибкой и приведет к выдаче предупреждения. Чтобы выполнить замену переменной, которая не является той $_, которую использует этот оператор, присвойте ей псевдоним $_ с помощью given, with или любым другим способом. Альтернативно используйте метод .subst.

Точно так же использование TR с ~~ является ошибкой (и, как отметил выше @raiph, , вероятно, должен выдать предупреждение ). Вместо этого вам следует установить $_ с помощью given/etc или использовать метод .trans.

Не уверен, есть ли у меня «практическое правило» на этот счет, но можно рассмотреть возможность использования s/// и tr/// только с sed-подобными -pe флагами командной строки (и/или ~~ смарт-сопоставителем, как показано в ОП) . Во всех остальных случаях используйте S/// и TR///, задав тему (например, с помощью given) при необходимости:

#Below works:

~$ raku -pe 's:g/\,/\t/;' file.csv

#OR

~$ raku -pe 'tr/,/\t/;' file.csv

Что сбивает с толку, так это то, что sed, как «редактор потока», выбирает значение из потока, изменяет его и помещает («возвращает») значение обратно в поток для вас. Коротко и понятно, но сильно отличается от awk или практически от любого другого динамичного языка, с которым вы можете играть.

Чтобы выполнить ту же задачу с awk и многими другими языками, вам понадобится явный оператор output с изменяемыми строками. Вот где действительно блестят обозначения «big-S» и «big-TR» (обратите внимание на -ne неавтопечатающие, awk-подобные флаги командной строки):

#Below works:

~$ raku -ne 'S:g/\,/\t/.put;'  file.csv

#OR 

~$ raku -ne 'TR/,/\t/.put;'  file.csv

Так что это может показаться странным, если вы не пишете однострочники, но вы можете просто запомнить из вышесказанного: чтение lines() из файла потребует нотаций «big-S» или «big-TR», как во втором (awk- подобный случай), в отличие от первого случая, подобного sed:

#Below with tr/// doesn't work:

~$ raku -e 'for lines() {tr/,/\t/.put};'  file.csv > file.tsv
Cannot modify an immutable Str (input,file,text,here...)
  in block <unit> at -e line 1

#Below with TR/// works as desired:

~$ raku -e 'for lines() {TR/,/\t/.put};'  file.csv > file.tsv

(Наконец, вы должны знать, что Raku покончил с -i редактированием файлов «на месте». У меня есть только неофициальные доказательства следующих рассуждений, но некоторые комментарии SO предполагают, что конечные пользователи Perl случайно «очищали» свои входные данные. файлы с неправильной комбинацией флагов командной строки и операторов «small-s» или «small-tr», отсюда и введение нотаций «big-S» или «big-TR», которые по своей сути более безопасны).

К вашему сведению, этот комментарий @BradGilbert предполагает, что S/// является заменой Perl s///r на Raku: nntp.perl.org/group/perl.perl6.users/2019/06/msg6777.html

jubilatious1 04.03.2024 07:02

Другие вопросы по теме