【问题标题】:Automatically parsing language strings from blade files从刀片文件中自动解析语言字符串
【发布时间】:2021-12-05 03:21:35
【问题描述】:

我想从刀片文件 ({{ __('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+?)?}/"

我知道这并不完美,我该如何进一步改进以更好地捕捉一些边缘情况,例如一些结束字符串打破了中间的捕捉?

【问题讨论】:

  • 您可能应该尝试查看您尝试过的插件,看看它们如何匹配所有内容。也许他们还涵盖了最终的边缘情况(不确定会是什么)
  • 他们没有,这就是我开始自己制作的原因。不过谢谢你的评论。

标签: php regex laravel


【解决方案1】:

我最近使用this github repo 作为基础做了这样的事情:

我在这里唯一需要的是实际的解析正则表达式和逻辑,可以在this file中找到

为简单起见,他们所做的是解析并匹配用于显示已翻译字符串的实际可能函数:___t@lang。通过这样做,它不再需要搜索和匹配花括号,因为如果您正在使用这可能会很痛苦:

  1. 过滤器:{{ __('whatever') | ucfirst }}
  2. 条件渲染:{{ $title ?? __('Whatever') }}

还有很多其他情况会让你的正则表达式发疯。

通过仅匹配函数,模式非常简单:

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

Here is a Regex101 example showcasing the cases you are looking for

【讨论】:

  • 关于我正在做的不必要的花括号匹配的好点。谢谢!
  • 很高兴它有效:)
  • 确实如此。你的正则表达式比我扔在墙上的要重要得多。干杯,我很感激。
【解决方案2】:

你尝试的模式,也可以写成

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

一些笔记

  • (?:\s+?)? 可以写成\s*?
  • (?:'|\") 可以使用字符类编写为['"]
  • (?:.+?)? 可以写成.*?
  • (?:\)|,)可以写成[),]

例如,为了防止字符串在捕获组中的单引号或双引号上中断,您可以使用 2 个否定字符类,从开始到结束单引号或双引号之间进行交替匹配。

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

Regex demo

  • {\s*{ 匹配 {{ 与可选的空白字符之间
  • .*?__ 匹配尽可能少的字符,然后匹配 __
  • \(\s* 匹配 ( 和可选的空白字符
  • ( 捕获第 1 组
    • "[^"]*" 匹配从开场" 到闭幕"
    • |或者
    • '[^']*' 匹配从开场' 到闭幕'
  • )关闭第一组
  • \s*[,)] 匹配可选的空白字符和,)
  • .*? 匹配尽可能少的字符
  • }\s*} 匹配 }} 与可选的空白字符之间

Regex demo


注意 .*? 可以匹配除换行符以外的任何字符。对于示例数据,您可以用匹配可选空白字符的\s* 替换这两个匹配项。

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

Regex demo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-23
    • 2014-02-28
    • 1970-01-01
    • 2014-03-15
    • 2011-03-08
    • 1970-01-01
    相关资源
    最近更新 更多