Прежде чем я скажу вам, что вам нужно делать правильно, давайте посмотрим, что вы делаете неправильно:
$char =~ s/.|$/|/g;
Проблема здесь в том, что и .
, и |
являются метасимволами в регулярных выражениях. |
означает «или», то есть вы говорите «соответствует .
или $
». Вы правильно знаете, что $
означает конец строки, но .
означает «любой один символ». Таким образом, он немедленно соответствует одному символу и продолжает немедленно соответствовать одному символу, каждый раз меняя этот символ на |
(метасимволы не применяются во второй половине выражения s///
), затем он соответствует концу строки и добавляет |
там. Или что-то типа того. По сути, не то, что вы хотите, чтобы произошло.
$char =~ s/[.|]$/|/g;
Ну, внутри []
s, .
и |
перестают быть метасимволами, но []
означает «один из них», так что это регулярное выражение ищет символ перед концом строки, и если это либо |
, либо .
, оно меняется на |
. Опять же, не то, что вы хотите, чтобы это произошло.
$char = tr/.|//d; # and later add |.
tr
не тот инструмент для этой работы. Это приведет к удалению всех символов .
и |
в вашей строке. Предположим, вы используете не оператор сопоставления регулярных выражений * 1032, а оператор присваивания =
. Определенно не то, что вы хотите, чтобы произошло.
То, что вы хотите, это:
$char =~ s/\.\|$/|/;
Мы избежали как .
, так и |
с \
, поэтому Perl знает, что «символ после \
является буквенным символом без специального значения *» и соответствует литералу .|
в конце вашей строки и заменяет его просто |
.
Тем не менее, звучит так, будто вы новичок в регулярных выражениях. Я большой поклонник perldoc perlretut
, который, я думаю, является одним из лучших (если не лучших) введений в регулярные выражения в Perl. Вы должны действительно прочитать это - регулярные выражения - мощный инструмент в руках тех, кто их знает, и сильная головная боль для тех, кто не знает.