【问题标题】:Regular expression to determine key正则表达式确定键
【发布时间】:2025-12-14 00:30:01
【问题描述】:

在我的 Angular 应用程序中,我正在使用支持定义自定义转译器的翻译服务。转译器根据翻译文件中的内容接收传入的翻译。有些是纯翻译,您也可以将对象传递给翻译(例如label.profile.greeting 翻译键):

{
  "label.startpage.welcome": "Welcome!",
  "label.startpage.info": "This website is awesome. Hope you like it.",
  "label.profile.greeting": "Hi, {{username}}."
}

当服务尝试翻译时,它会遍历翻译中的所有单词并将该单词发送到转译器。然后转译器会尝试确定它是简单的翻译,还是需要注入到翻译中的对象。

然而,我的转译器能够将翻译注入其他翻译:

{
  "label.favourite": "My favourite fruit is",
  "label.favourite.banana": "{{label.favourite}} banana!",
  "label.favourite.pineapple": "{{label.favourite}} pineapple!"
}

我编写了这个简单的箭头函数,我的编译器使用它来确定传入的翻译是否是翻译键:

const isTranslationKey = (value: string): boolean => /(\w+(?:\.\w+)+)/.test(value);

而且它有效。尽管由于正则表达式的安全敏感性according to SonarQube,此正则表达式具有很高的安全风险。我想这可能是导致未来失败的原因的字符串长度,因为字符串没有最大限制。而且我尝试将正则表达式更改为类似的东西,但我无法判断它是否更合适:

/^([A-Za-z]{1,10})+(\.([A-Za-z]{1,10})).{1,40}$/

我需要一些这方面的专业知识。提前致谢! :)

【问题讨论】:

  • 如果您不想在3.43.43.335 中找到匹配项,请将/(\w+(?:\.\w+)+)/ 替换为/^[a-z]+(?:\.[a-z]+)+$/i。这不是一个邪恶的正则表达式,无视 SonarQube,它的规则对于正则表达式来说太严格了,并且在 99% 的情况下都是误报(当然对于正确编写的模式)。
  • 谢谢你,@WiktorStribiżew 我会使用你的表达方式,因为它严格使用字母,中间没有任何内容。似乎更符合逻辑。我刚刚发现了前瞻,所以我在你的表达式中添加了这个:/^(?=.{3,61}$)([a-z]+(?:\.[a-z]+)+)$/i。所以不会超过60个字符
  • 如果不超过60个字符且至少3个字符,可以使用/^(?=.{3,60}$)[a-z]+(?:\.[a-z]+)+$/i

标签: javascript angular regex


【解决方案1】:

您可以使用的最终正则表达式可以是两者之一,具体取决于您是否需要支持所有 Unicode 字母:

/^(?=.{3,60}$)[a-z]+(?:\.[a-z]+)+$/i
/^(?=.{3,60}$)\p{L}+(?:\.\p{L}+)+$/u

请注意,第二个正则表达式符合 ECMAScript 2018,在使用它之前,请确保您的 JavaScript 环境支持它。

详情

  • ^ - 字符串开头
  • (?=.{3,60}$) - 一个正向前瞻,需要三到六十个字符,而不是换行符,紧跟在当前位置右侧的字符串结束位置
  • [a-z]+ - 一个或多个 ASCII 字母(任何 Unicode 字母,如果您使用 \p{L}\p{Alphabetic}
  • (?:\.[a-z]+)+ - . 的一个或多个重复和一个或多个 ASCII 字母(如果您使用 \p{L} / \p{Alphabetic},则为任何 Unicode 字母)
  • $ - 字符串结束。

请参阅regex demo

【讨论】: