За последние 24 часа нас посетили 20685 программистов и 1631 робот. Сейчас ищут 1153 программиста ...

Детали реализации строк в PHP

Тема в разделе "PHP для новичков", создана пользователем cycymora, 31 май 2021.

Метки:
  1. cycymora

    cycymora Активный пользователь

    С нами с:
    31 май 2021
    Сообщения:
    8
    Симпатии:
    0
    Код (PHP):
    1. <?
    2. // 1) Объясните пожалуйста в деталях реализации, почему строки не равны:
    3. ("\0"."41")  != "\041";
    4.  
    5. // 2) Существует ли способ вывода символа без использования chr()
    6. // формируя строку, так "\0"."$num", или "\0$num", или еще как-либо,
    7. // например через var_dump()?
     
  2. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.796
    Симпатии:
    1.331
    Адрес:
    Лень
    "�41" != "!"
    var_dump ( "\0"."41", "\041" );
     
  3. Drunkenmunky

    Drunkenmunky Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.491
    Симпатии:
    281
    PHP:
    1. printf("%c", 41);
     
  4. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.593
    Симпатии:
    362
  5. cycymora

    cycymora Активный пользователь

    С нами с:
    31 май 2021
    Сообщения:
    8
    Симпатии:
    0
    Так об этом и речь, что вроде как получается, что или нельзя получить символ ASCII из конкатенации 2х строк. Или я не понимаю как их сконкатенировать.

    Спасибо!
    //---------------------------------------------------------------------

    Спасибо!
    //---------------------------------------------------------------------

    Спасибо!
    //---------------------------------------------------------------------

    Вообще сам вопрос возник на почве чтения документации из раздела строки. А именно:
    "... \[0-7]{1,3} - последовательность символов, соответствующая регулярному выражению символа в восьмеричной системе счисления, который молча переполняется, чтобы поместиться в байт (т.е. "\400" === "\000") ... "

    На почве этого возникла навязчивая идея выводить символы ASCII путем формирования в цикле регулярного выражения, для управляющей последовательности, которое в двойных кавычках будет превращаться в символ. Глаза кровью налились, а вот найти способ сформировать регэксп управляющей последовательности для вывода символов ASCII я так и не смог. Думал может здесь кто знает, но в итоге вопросы сформулировал не точно.

    В общем за ответы спасибо, но вопросы переформулирую в один:
    Возможно ли именно сформировать, а не задать как константу регулярное выражение соответсвующее символу ascii, которое в последствии в двойных кавычках интерпретатор сможет транслировать как управляющую последовательность символа ascii и вывести этот символ?
     
    #5 cycymora, 1 июн 2021
    Последнее редактирование: 1 июн 2021
  6. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.593
    Симпатии:
    362
    Если формируете в восьмеричке - можно преобразовать код в 10 систему счисления и вывести через chr()
    Например:
    PHP:
    1. $prefix = "0";
    2. $num = "41";
    3. // Вариант 1
    4. $foo = base_convert($prefix . $num, 8, 10);
    5. echo $foo . "\n";
    6. echo chr($foo) . "\n";
    7. // Вариант 2
    8. $foo = intval($prefix . $num, 8);
    9. echo $foo . "\n";
    10. echo chr($foo) . "\n";
    Но ведь можно сразу в десятичной системе счисления формировать?
     
  7. cycymora

    cycymora Активный пользователь

    С нами с:
    31 май 2021
    Сообщения:
    8
    Симпатии:
    0
    Видите, сам вывод символа по его коду задача простая. Она придумалась, просто для примера, в котором символ вычисляется програмно. Но мне хочется уметь не столько вывести символ по его коду, сколько сформировать регулярное выражение, которое может быть распознано как управляющая последовательность символа в строке из двойных кавычек.

    Согласно документации такая последовательность может быть в восьмеричной (\[0-7]{1,3}) или шестнадцатеричной (\x[0-9A-Fa-f]{1,2}) системе счисления или символом юникода (\u{[0-9A-Fa-f]+}).

    Если я правильно понимаю, что на писано в документации в разделе про управляющие последовательности в строках в двойных кавычках, то тот факт, что в используемом мною регекспе имеется ведущий нуль не влияет на то восьмеричная система или нет. В моем примере система восьмеричная по тому, что после слеша остутсвуют "x" и "u" и используются цифры меньше 8. Т.е. Например, в данном случае записи var_dump("\041"); и var_dump("\41"); эквивалентны и интерпретируются как записи в восьмиричной системе.

    Меня не устраивает, тот факт, что я не умею сформировать такую строку из нескольких частей. Т.е. нет проблемы написать восклицательный знак как константную строку так "\41", но неужели нет способа сформировать такую строку в результате какого-нибудь вычисления в программе? Вот у меня например, не получается вывести восклицательный знак например так: $n = "1"; var_dump("\4$n");

    В общем вопрос сводится к двум вариантам - или я дурак и что-то очевидное в операциях со строками не просекаю или тут имеет место ограничение языка. Что вы на этот счет думаете?
     
    #7 cycymora, 1 июн 2021
    Последнее редактирование: 1 июн 2021
  8. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    922
    Симпатии:
    143
    А можно уточнить цель таких извращений? Создание нечитаемого кода?
     
  9. cycymora

    cycymora Активный пользователь

    С нами с:
    31 май 2021
    Сообщения:
    8
    Симпатии:
    0
    Префекционизм. Хочу понимать, что я действительно понимаю строки в php.
     
  10. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.796
    Симпатии:
    1.331
    Адрес:
    Лень
    Спустя 13 пачек сигарет..
     
  11. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    922
    Симпатии:
    143
    Тут верно.

    Так в код символа не склеивается, "\4" отдельно, $n отдельно.
     
  12. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.593
    Симпатии:
    362
    Экранирующие последовательности. В первых двух абзацах и "замечании".
    (\[0-7]{1,3}).
    Загвоздка, однако, в слешике?
    "(\\[0-7]{1,3})" или '(\\[0-7]{1,3})'
    То есть экранирование обратного слеша выполняется тоже обратным слешем.
    --- Добавлено ---
    Пример в песочнице
     
  13. php8guru

    php8guru Новичок

    С нами с:
    24 янв 2021
    Сообщения:
    14
    Симпатии:
    1
    "\0"."41"

    Тут проблема, \0 это экранированный символ, он переводится в код, а 41 просто число.
    \041 это не тоже самое