1. Куча / Говнокод #13477

    +124

    1. 1
    "(\{\{([#%$])([^:\}]+)(:([^\}]+))?\}\})"

    Регуляркоговно.
    Заменено на

    "(\{\{([#%$])(.+?)(:(.+))?\}\})"

    Запостил: vistefan, 25 Июля 2013

    Комментарии (32) RSS

    • Возможно стоило бы привести то в каком контексте это дело было использовано. Потому как мне кажется эти регулярные выражения немного различны и предложенные vistefan вариант будет охватывать большее количество вариантов нежели тот что представлен как регуляркоговно. Хотя - могу ошибаться.
      Ответить
    • Макаки, про \Q \E слышали? Тоже гавно, но хоть не такое.
      Ответить
      • Макаки просто не знают, что это такое.
        Ответить
        • Ну и чем \Q{{\E будет лучше чем \{\{? Оно все-таки предназначено для более длинных строк.
          Ответить
    • Выражение типа .+? как раз таки обычно говно, т.как всегда можно найти более конкретное выражение, описывающее, что нужно искать. С моей точки зрения vistefan скорее ухудшил, чем улучшил.
      (:(.+))? - это вообще что-то мозговыносящее. Зачем?
      Ответить
      • > (:(.+))? - это вообще что-то мозговыносящее. Зачем?
        Опциональное двоеточие с неким текстом после него.

        Как я понял регулярка парсит такие выражения:
        {{$a:b}}
        {{%aaaa}}
        {{#bbb:cc}}
        Вопрос к ОП'у: это какой-то шаблонизатор?
        Ответить
        • Зачем нужны скобки внутри? Просто если стоит вопросительный знак после внешних скобок, это нужно понимать так, что внутренней группы может и не быть (и на ее присутстиве не рассчитывают). Либо если эту группу используют, то не понятно, как быть с нумерацией. Вобщем, хз, если эту группу предполагалось как-то использовать, я бы все равно отказался от внутренних скобок, и сделал бы так: (:.+)?, но т.как дальше есть еще какие-то условия, то, сделал бы так: (:[^}]+)?
          Ответить
          • > Зачем нужны скобки внутри?
            Для захвата видимо. Меня другой вопрос волнует - зачем нужны скобки снаружи, вокруг всего выражения ;)

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

            > я бы все равно отказался от внутренних скобок, и сделал бы так: (:.+)?,
            Тогда придется ":" отрезать в коде, что тоже не айс.
            Ответить
            • > отрезать в коде
              Ну в том-то и дело, что отрезать в коде - проще и дешевле, а если эта группа как-то должна была использоваться через \N или $N - то ее явно таким способм использовать не получится.
              Ответить
              • > проще и дешевле
                Чем дорисовать пару скобочек и брать значение из следующей группы? Да ну? :)

                > то ее явно таким способм использовать не получится
                Почему?
                Ответить
                • UPD:
                  группа 1 - весь тег {{$aa:bb}} или {{$aa}}
                  группа 2 - один символ $ % или #
                  группа 3 - aa
                  группа 4 - :bb, если оно есть
                  группа 5 - bb, если оно есть
                  Ответить
                  • Ну с точки зрения программиста - может и удобнее, но мы бы получили две практически одинаковые копии, одна из которых не нужна.

                    А как ее использовать, если она может быть, а может и не быть?

                    >>> re.sub(r'(f)(:(x))?', r'-\3-', 'foo')
                    Traceback (most recent call last):
                      File "<stdin>", line 1, in <module>
                      File "/usr/lib64/python2.7/re.py", line 151, in sub
                        return _compile(pattern, flags).sub(repl, string, count)
                      File "/usr/lib64/python2.7/re.py", line 275, in filter
                        return sre_parse.expand_template(template, match)
                      File "/usr/lib64/python2.7/sre_parse.py", line 787, in expand_template
                        raise error, "unmatched group"
                    sre_constants.error: unmatched group
                    >>> re.sub(r'(f)(:(x))?', r'-\2-', 'foo')
                    Traceback (most recent call last):
                      File "<stdin>", line 1, in <module>
                      File "/usr/lib64/python2.7/re.py", line 151, in sub
                        return _compile(pattern, flags).sub(repl, string, count)
                      File "/usr/lib64/python2.7/re.py", line 275, in filter
                        return sre_parse.expand_template(template, match)
                      File "/usr/lib64/python2.7/sre_parse.py", line 787, in expand_template
                        raise error, "unmatched group"
                    sre_constants.error: unmatched group
                    >>> re.sub(r'(f)(:(x))?', r'-\1-', 'foo')
                    '-f-oo'
                    >>>
                    Ответить
                    • Хм. А я думал, что раз в groups() значение есть в любом случае (None для незаматченных), то и в sub прокатит... Значит я ошибался.
                      Ответить
                      • Оно как-то в разных языках по-разному, мне встречались всякие варианты поведения. Ж.скрипт реагирует заменой на пустую строку, но где-то мне встречалось, что в строку попадала подстрока "$N" и т.д.
                        Ответить
                        • Это PHP, там всё работает именно так, как предполагал bormand.
                          Ответить
                          • В питоне groups'ы тоже возвращаются полностью, даже если скобка не заматчилась. И в перле. Видимо это общая фишка регекс движков. А вот по подстановке \1 \2 действительно разное поведение.
                            Ответить
        • Да, это шаблонизатор. Формат тегов вы поняли верно.
          Ответить
          • А чем готовые шаблонизаторы не подошли, если не секрет?
            Ответить
            • мне кажется, это риторический вопрос
              Ответить
            • у них был фатальный недостаток
              Ответить
            • Как уже верно заметили, классика жанра же.
              Плох тот похапешнег, что не написал своего шаблонизатора, своей CMS, ...
              На самом деле я уже постил часть этого шаблонизатора здесь пару говнокодов назад, где меня закидали какахами, уверяя, что пускать контроллер в область видимости данных, буферить вывод в переменную и возвращать назад - это нормально. Шаблонизатор специфичен, он построен на антипаттерне, пропагандирует "толстые контроллеры", а сам при этом всего пол сотни строк занимает. Зато бузиннес логику от верстки отделяет хорошо.
              Ответить
    • P.S. Нижняя регулярка багует на {{$a:}}, возвращая "a:" вместо "a" в третьей группе (.+?). Верхняя регулярка на таком вводе просто не матчилась. Или я туплю?
      Ответить
      • Верно. Может быть так?
        '/\{([#%$])(.+?)(:(.+)?)?\}/'
        Тогда оно будет лояльно к двоеточию на конце.
        Ответить
        • fix: но только фигурные скобки надо продублировать.
          Ответить
    • Что то говно, что то. Ибо ни хрена не понятно, что оно делает
      Ответить
      • bormand понял, что оно делает. Видимо вам не хватает опыта.
        Ответить

    Добавить комментарий