Косые черты и хэши в Perl и метасимволы - PullRequest
1 голос
/ 15 февраля 2011

Спасибо за предыдущую помощь всем! У меня есть вопрос относительно RegExp в Perl

Моя проблема ..

Я знаю, что при сопоставлении вы можете написать m // или // или ## (должно включать m или s, если вы используете это). Что вызывает у меня путаницу, так это пример из книги о том, как убежать от своих персонажей. Я полагаю, что большинство людей избегают множества символов, как верный способ работы программы, не пропуская метасимвол, например: \ @ при поиске совпадения @ скажем в адресе электронной почты.

Вот моя проблема, и я знаю, что делает этот скрипт:

$date= "15/12/99"
$date=~ s#(\d+)/(\d+)/(\d+)#$1/$2/$3#; << why are no forward slashes escaped??
print($date);

Тем не менее, последний пример, который я имею, показывает, что он переписан, как (что я тоже понимаю, и они избежали)

$date =~ s/()(\d+)\/(\d+)\/(d+)/$2\/$1\/$3; <<<<which is escaping the forward slashes.

Я знаю, что косые черты или хэши являются предпочтением программиста и их использование. Чего я не понимаю, так это того, почему второй пример избегает слэшей, а первый - нет - я пробовал, и они работают в обоих направлениях. Никаких слэшей с хэшами? Еще больше сбивает с толку то, что, глядя на еще один пример книги, который я также ранее приводил к этому, снова используя хэши, они тоже избегают символа @.

if ($address =~ m#\@#) { print("That's an email address"); } или что-то подобное

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

Ответы [ 6 ]

8 голосов
/ 15 февраля 2011

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

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

Конечно, то же правило применяется ко всем символам, которые вы используете в качестве разделителя регулярных выражений, а не только к косой черте.

3 голосов
/ 15 февраля 2011

На сам вопрос был дан правильный ответ в нескольких ответах. Но все, что вы всегда хотели знать о регулярных выражениях Perl, но, возможно, боялись спросить, можно найти в perldoc perlre , perldoc perlrequick и perldoc perlretut . Я рекомендую вам прочитать их.

3 голосов
/ 15 февраля 2011

Косые черты не являются метасимволами сами по себе - их использование только во втором примере в качестве разделителей выражений делает их «специальными».

Формат выражения замены:

s<expression separator char><expression to look for><expression separator char><expression to replace with><expression separator char>

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

3 голосов
/ 15 февраля 2011

Оператор соответствия regex позволяет определить пользовательский непробельный символ в качестве разделителя.

В вашем первом примере в качестве разделителя используется знак «#».Так что в этом регулярном выражении вам не нужно избегать «/», потому что оно не имеет особого значения.Во втором регулярном выражении символ разделителя не изменяется.Поэтому используется значение по умолчанию «/».Теперь вы должны избегать всех «/» в вашем шаблоне.Иначе парсер запутается.:)

2 голосов
/ 15 февраля 2011

Если вы не используете косую черту, рекомендуется использовать фигурные скобки и модификатор / x.

$date=~ s{ (\d+) \/ (\d+) \/ (\d+) }{$1/$2/$3}x;

Экранирование не алфавитно-цифровых символов также является стандартом, даже если они не являются метафайлами.персонажи.Смотри perldoc -f quotemeta.

0 голосов
/ 28 октября 2013

В этом вопросе есть еще одна глубина - экранирование косой черты с помощью модификатора s.В моем примере захват становится проблемой.

$image_name =~ s/((http:\/\/.+\/)\/)/$2/g;

Чтобы это работало, опечатка с добавлением второй косой черты должна была быть захвачена.Кроме того, попытка работать только с двумя слэшами не сработала.Первый слеш должен сопровождаться более чем одним персонажем.Изменение "http://world.com/Photos//space_shots/out_of_this_world.jpg"
на:" http://world.com/Photos/space_shots/out_of_this_world.jpg"

...