Традиционный способ изменить foo
на bar
в строке - это сделать:
$string =~ s/foo/bar/;
Это все хорошо, но что если foo
и bar
содержат много символов /
? Например, что если вы хотите изменить все экземпляры http://
на https://
? Вам нужно будет убрать символы /
с помощью \
, и вы увидите что-то вроде этого:
$string =~ s/http:\/\//https:\/\//;
Вы должны признать, что приведенная выше замена не так проста для глаз , Не так просто определить, какие /
принадлежат s///
, а какие http://
. А символы \
, используемые для экранирования символов /
, только затрудняют понимание всей строки.
Некоторые люди называют это «синдромом склонности зубочистки», потому что все /
и \
персонажи выглядят как зубочистки.
Хорошая новость заключается в том, что вам не нужно использовать /
при использовании s///
. Вместо этого вы можете использовать много других символов, что делает следующие строки эквивалентными приведенным выше:
$string =~ s#http://#https://#;
$string =~ s@http://@https://@;
$string =~ s!http://!https://!;
$string =~ s|http://|https://|;
Поскольку разделитель регулярных выражений больше не является значением по умолчанию /
, вам больше не нужно экранировать /
, что значительно облегчает чтение всей строки.
Вы должны были бы выйти из любого используемого разделителя, поэтому во избежание "синдрома наклоняющейся зубочистки" я бы посоветовал использовать разделитель, который не отображается в вашем выражении.
Есть много символов, которые вы можете использовать в качестве разделителей; Я не буду перечислять их здесь. Однако есть четыре специальных ограничителя скобка , которые входят в пары и окружают ваши выражения, как в скобках. Это: (
и )
, [
и ]
, {
и }
и, наконец, <
и >
. Вы используете их так:
$string =~ s(http://)(https://);
$string =~ s<foo><bar>g;
Немного легче читать без всех этих зубочисток, не так ли?
Ваше выражение подстановки будет легче читать, если используемый разделитель не не существует в самом выражении. (В противном случае вам придется убежать с помощью \
.)
Что немного странно в приведенном вами примере:
$string =~ s<(\d+)><$1\.>g;
Не существует ли символов /
где-нибудь в выражении, так что, предположительно, это не более понятно, чем:
$string =~ s/(\d+)/$1\./g;
Однако, возможно, оригинальный кодер думал, что два символа \
будут контрастировать с символами /
, и поэтому хотел избежать /
разделители в целом.
Примечание: Вы не спрашивали об этом, но часть замены $1\.
без необходимости экранирует символ .
. Вам не нужен \
там, потому что вторая часть подстановки s///
не является регулярным выражением - это только замена, и .
никогда не используется там, чтобы соответствовать символу. Так что нет смысла избегать его в вашем случае, так как .
всегда означает литерал .
там.
Так что вышеприведенная строка будет лучше записана как:
$string =~ s/(\d+)/$1./g;
I надеюсь, это поможет!