#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
. Делая это, ему больше не нужно искать и сопоставлять фигурные скобки, потому что это может быть проблемой в случае, если вы используете:
- Фильтры:
{{ __('whatever') | ucfirst }}
- условный рендеринг:
{{ $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"[^"]*"
Матч от открытия"
до закрытия"
|
Или'[^']*'
Матч от открытия'
до закрытия'
)
Близкая группа 1s*[,)]
Сопоставьте необязательные символы пробелов и либо,
или)
.*?
Сопоставьте как можно меньше символов}s*}
Сопоставление}}
с дополнительными символами пробелов между ними
Демонстрация регулярных выражений
Обратите внимание, что .*?
может совпадать с любым символом, кроме новой строки. Для примера данных вы можете заменить эти 2 вхождения s*
соответствующими необязательными символами пробелов.
{s*{s*__(s*("[^"]*"|'[^']*')s*[,)]s*}s*}