We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 31022
    • 328 Posts
    Дядьки и тетьки (с), а помогите, пожалуйста, с регуляркой. Я совсем не программист, и в тонкостях не разбираюсь (да и вопрос не про MODx), но, думаю, что для спеца это пустяковый вопрос.

    Итак, задача. Нужно вставить картиночку в последнюю строчку последнего параграфа на странице. Эдакий концевой элемент. Что я делаю. Для простоты задачи, в шаблое вкорячил уникальный элемент после поля [*content*]: <!-- contentEnd -->. Соответственно, в коде у меня должна получиться уникальная по документу строка </p><!-- contentEnd -->, которую я могу заменять на <img></p>. Вроде бы, все просто.

    Создал плагин по образу и подобию плагина из хелпа. Там в замене используется str_replace(). И она бы меня устроила, и не надо никаких регулярок, если бы не одно но. После завершающего </p> в коде (оказывается!) возможно наличие символов перевода строки, пробелов или еще чего-то. Ввиду этого пришлось использовать preg_replace() -- по образу плагина Google Analytics.

    Соответственно, пишу:
    $modx->documentOutput = preg_replace("/(<\/p>(\s{,3})<\!-- contentEnd -->)/i", $withImage, $modx->documentOutput);


    Вот и вопрос: что поставить заместо (\s{,3})? Посмотрел доки по регуляркам, пробовал и просто \s и со всякими комбинациями +? и т.п. И просто ?, и *. Не работает. В смысле, работает не всегда. Где нету символа между p и комментарием -- картинка выводится, а где есть что-то (что!?) -- нет.


    Как обозначить эти неизвестные символы в регулярке? Есть ли другое решение?

    Надеюсь на помощь. Спасибо!
      • 33694
      • 742 Posts
      Как же это ты доку читал, и не увидел, что точка - это любой символ.
      Попробуй так: preg_replace("/<\/p>.*<\!-- contentEnd -->/i", ...

      * скобки там можно поубирать везде
        • 31022
        • 328 Posts
        Мда, ступил. Вот что читал:
        * \s - если вы в условии поиска поставите друг за другом символ обратного слеша, а после него сразу букву s, то таким образом вы опишите либо пробел, либо символ табуляции. Конечно в условии поиска можно поставить пробел так, как вы его обычно ставите на письме, но запись [a-z\s] будет намного понятнее и читабельней чем [a-z ], с первого взгляда видно, что в первый символьный класс входит пробел, а вот со вторым символьным классом надо присмотреться, а так как регулярные выражения итак представляют для многих набор значков, то пропустить пробел, поставленный таким образом будет очень просто. Внимательно используйте этот спецсимвол, так в дополнении к тому, что он совпадает с пробелом и табулятором, он совпадет также с символом новой строки.
        * \S - скажу просто, что в своем большинстве это видимые символы, т.е. все, что не совпадает с \s
        * \w - спецсимвол, который призван заменить целый символьный класс, в него входят все символы, которые могут входить в слово, обычно это [a-zA-Z_], хотя много может зависеть от установленной локали, поддержки юникода и т.д.
        * \W - все что не входит в определение \w. либо [^a-zA-Z_]
        * \d - все цифры т.е. уже известный вам символьный класс [0-9]
        * \D - все, что не является цифрой

        А после этого сразу идет абзац
        Как видите, часто спецсимволы описывают какие-то частоиспользуемые множества символов, которые используются программистами каждый день, но эти множества имеют границы, т.е. либо цифры, либо буквы и подчеркивание, либо невидимые символы, но как описать все символы? Просто! Надо поставить точку!
        Его, естественно, я не прочитал.

        (отсюда: _http://www.phpclub.ru/detail/article/regexp_1)

        Спасибо большое, пойду применять.
          • 31022
          • 328 Posts
          Неа, не работает ’.*’ sad По-прежнему, где нет ничего -- срабатывает, где есть перевод строки (видимо) --нет, не заменяется. Как это?

          UPD О! Вот как заработало:

          preg_replace("/<\/p>(\s*|.*)<\!-- contentEnd -->/i"...


          Или перевод строки сколько угодно раз или любой символ тоже квантифицирован как *

          Если работает -- оставить? Или можно проще?

          UPD 2 Ггг, лучше, все-таки, ограничить количество любых символов, а то эта штука сжирает даже концовки таблиц и дивов.

          preg_replace("/<\/p>(\s*|.{,3})<\!-- contentEnd -->/i"...

            • 33694
            • 742 Posts
            Нужно просто нежадное совпадение использовать — после звёздочки знак вопроса ставить (вроде так). Тогда оно будет захватывать по минимуму.
              • 26704
              • 115 Posts
              Не знаю актуально ли это, но в сети есть замечательный сервис для тестирования рег выражений. Там же вы можете найти готовые решения и описание правил семантики:

              http://regxlib.com/
              http://regxlib.com/RETester.aspx

              сама постоянно пользуюсь второй ссылкой.