Дополнительная обратная косая черта, необходимая для PHP регулярного выражения

При тестировании ответа на вопрос другого пользователя я нашел то, что я не понимаю. Проблема заключалась в том, чтобы заменить все литералы \t \n \r из строки одним пространством.

Теперь, первый образец, который я пробовал, был:

 /(?:\\[trn])+/ 

что на удивление не сработало. Я пробовал такую ​​же модель в Perl, и она работала нормально. После некоторых проб и ошибок я обнаружил, что PHP хочет иметь 3 или 4 обратных слэша для этого шаблона, как в:

 /(?:\\\\[trn])+/ 

или

 /(?:\\\[trn])+/ 

эти модели – к моему удивлению – оба работают. Почему эти дополнительные обратные косые черты необходимы?

Вам нужно 4 обратных слэша для представления 1 в регулярном выражении, потому что:

  • 2 обратных слэша используются для unescaping в строке ( "\\\\" -> \\ )
  • 1 обратная косая черта используется для unescaping в двигателе регулярных выражений ( \\ -> \ )

Из документа PHP,

экранирование любого другого символа приведет к тому, что обратная косая черта будет напечатана слишком 1

Следовательно, для \\\[ ,

  • 1 обратная косая черта используется для unescaping \ , одно пребывание, потому что \[ недопустимо ( "\\\[" -> \\[ )
  • 1 обратная косая черта используется для unescaping в двигателе регулярных выражений ( \\[ -> \[ ]

Да, это работает, но не очень хорошая практика.

Его работы в perl, потому что вы передаете это непосредственно как шаблон регулярного выражения /(?:\\[trn])+/

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

 "/(?:\\\\[trn])+/" 

Регулярное выражение \ в соответствии с одним обратным слэшем станет «/ \\\\ /» в качестве строки preg PHP

Регулярное выражение есть просто /(?:\\[trn])+/ . Но так как вам нужно избегать обратных косых черт в декларациях строк, каждый обратный слэш должен быть выражен с помощью \\ :

 "/(?:\\\\[trn])+/" '/(?:\\\\[trn])+/' 

Просто три пробела также работают, потому что PHP не знает escape-последовательности \[ и игнорирует его. Итак \\ станет \ но \[ останется \[ .

Используйте str_replace!

 $code = str_replace(array("\t","\n","\r"),'',$code); 

Должен сделать трюк