Автоматический анализ языковых строк из блейд-файлов

#php #regex #laravel

Вопрос:

Я хотел бы проанализировать языковые строки из блейд-файлов ( {{ __('some phrase') }} ) и автоматически сохранить их в языковых файлах. Я попробовал плагин, связанный с этим, который работал нормально, но не позволял запускать функции. Я создал приведенное ниже регулярное выражение.

 {                              // Opening curly brace
    (?:s ?)?                  // Optional spacing
    {                          // Opening curly brace
        (?:s ?)?              // Optional spacing
        (?:. ?)?               // Optional function
            __(               // Begin translation function
                (?:s ?)?      // Optional spacing
                    (?:'|")   // Single or double quote

                        (. ?)  // Actual string to capture

                    (?:'|")   // Single or double quote
                (?:s ?)?      // Optional spacing
            (?:)|,)           // End translation function, basically
        (?:. ?)?               // Ending optional function
        (?:s ?)?              // Optional spacing
    }                          // Ending curly brace
    (?:s ?)?                  // Optional spacing
}                              // Ending curly brace
 
 "/{(?:s ?)?{(?:s ?)?(?:. ?)?__((?:s ?)?(?:'|")(. ?)(?:'|")(?:s ?)?(?:)|,)(?:. ?)?(?:s ?)?}(?:s ?)?}/"
 

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

Комментарии:

1. Вероятно, вам следует попытаться взглянуть на плагин, который вы пробовали, и посмотреть, насколько они соответствуют всему. Возможно, они также охватывали возможные крайние случаи ( не уверен, какими они будут).

2. Они этого не сделали, и именно поэтому я начал кататься самостоятельно. Тем не менее, спасибо вам за комментарий.

Ответ №1:

Недавно я сделал что-то подобное, используя это репозиторий github в качестве основы:

Единственное, что мне здесь было нужно, — это фактический анализ регулярных выражений и логики, которые можно найти в этом файле

Чтобы все было просто, они проанализировали и сопоставили фактические возможные функции, используемые для отображения переведенных строк: __ , _t , @lang . Делая это, ему больше не нужно искать и сопоставлять фигурные скобки, потому что это может быть проблемой в случае, если вы используете:

  1. Фильтры: {{ __('whatever') | ucfirst }}
  2. условный рендеринг: {{ $title ?? __('Whatever') }}

И есть много других случаев, которые могли бы свести с ума ваше регулярное выражение.

Сопоставляя только функции, шаблон довольно прост:

/(__|_t|@lang)(h*['"](. )['"]h*[),]/U

Вот пример регулярного выражения 101, демонстрирующий случаи, которые вы ищете

Комментарии:

1. Хорошее замечание по поводу ненужного сопоставления фигурных скобок, которое я делал. Спасибо!

2. Рад, что это работает 🙂

3. Оно делает. Ваше регулярное выражение гораздо более уместно, чем то, что я швырнул в стену. Ваше здоровье, я ценю это.

Ответ №2:

Шаблон, который вы пробовали, также может быть записан как

 {s*{.*?__(s*['"](. ?)['"]s*[,)].*?}s*}
 

Несколько заметок

  • (?:s ?)? может быть записано как s*?
  • (?:'|") может быть записан с использованием класса символов как ['"]
  • (?:. ?)? может быть записано как .*?
  • (?:)|,) может быть записано как [),]

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

 {s*{.*?__(s*("[^"]*"|'[^']*')s*[,)].*?}s*}
 

Демонстрация регулярных выражений

  • {s*{ Сопоставление {{ с необязательным символом пробела между ними
  • .*?__ Сопоставьте как можно меньше символов, затем сопоставьте __
  • (s* Совпадающие ( и необязательные символы пробелов
  • ( Группа захвата 1
    • "[^"]*" Матч от открытия " до закрытия "
    • | Или
    • '[^']*' Матч от открытия ' до закрытия '
  • ) Близкая группа 1
  • s*[,)] Сопоставьте необязательные символы пробелов и либо , или )
  • .*? Сопоставьте как можно меньше символов
  • }s*} Сопоставление }} с дополнительными символами пробелов между ними

Демонстрация регулярных выражений


Обратите внимание, что .*? может совпадать с любым символом, кроме новой строки. Для примера данных вы можете заменить эти 2 вхождения s* соответствующими необязательными символами пробелов.

 {s*{s*__(s*("[^"]*"|'[^']*')s*[,)]s*}s*}
 

Демонстрация регулярных выражений