regex - Postgres 中的非贪婪捕获组

标签 regex postgresql regex-lookarounds regex-greedy

我正在尝试实现一个正则表达式来解析字符串的不同组。我提供的字符串表明客户想要将我们平台上的主要语言从 X 更改为 Y,因此它看起来像

  • language_change__from_english_to_spanish
  • language_change__from_spanish_to_somali
  • language_change__from_simplified_chinese_to_english

我有一个正则表达式来解析语言(原始语言,然后是新语言):

SUBSTRING(language_field FROM '^language_change__([a-zA-Z_]+)_to_[a-zA-Z_]+$')

这对于原始语言来说效果很好,但对于新语言来说效果不佳,因为有时人们输入了 language_change__from_english_to_spanish_ 。所以实际解析出来的是spanish_而不是spanish .

我知道我可以轻松地包裹我的 SUBSTRING(...)REPLACE替换最后的_ ,但我正在尝试找到一种使用正则表达式来提高我的正则表达式技能的方法。我基本上想忽略最后的_ 。但是,我无法删除 _来 self 的捕获组,因为我们系统中编码的某些语言有 _ :simplified_chinese ,例如。

基本上,我希望我的捕获组包含第一个 _后跟文本(如 simplified_chinese ),但不包括 _如果它位于字符串的末尾 ( english_ )。

所以当 language_change__from_spanish_to_english_输入后,我仍然应该捕获 english ,而不是english_作为语言。

我尝试了多种方法:

  • 使用负前瞻:SUBSTRING(language_field FROM '^language_change__[a-zA-Z_]+_to_([a-zA-Z_]+)(?!_)$')
  • 使用非贪婪捕获组:SUBSTRING(language_field FROM '^language_change__[a-zA-Z_]+_to_([a-zA-Z_]+?)$')
  • 使用负向先行和非贪婪捕获组的组合:SUBSTRING(language_field FROM '^language_change__[a-zA-Z_]+_to_([a-zA-Z_]+?)(?!_)$')

我觉得我已经在 StackOverflow 上待了足够长的时间,不会说“没有任何作用”,但我上面尝试过的所有三件事仍然产生 english_而不是english当人们错误地输入language_change__from_spanish_to_english_时在我们这边。

有人可以给我一些我缺少的东西吗?

最佳答案

您可以使用

SUBSTRING(language_field FROM '^language_change__[a-zA-Z_]+_to_([a-zA-Z_]+?)_*$')

([a-zA-Z_]+?)_*$ 部分的含义是:

  • ([a-zA-Z_]+?) - 第 1 组:匹配 1 个或多个 ASCII 字母或 _ 尽可能少的次数
  • _* - 匹配 0 个或多个 _ 字符
  • $ - 位于字符串末尾。

([a-zA-Z_]+?) 模式将匹配 1 个字符,然后将尝试 _*$ 模式部分。如果 _*$ 无法匹配,引擎将回溯,并且 ([a-zA-Z_]+?) 模式将获取另一个字符,并且测试将重复。因此,如果_存在于字符串末尾,它们将不会包含在捕获组中,它们将与_*部分匹配,因此将被从结果中丢弃。

参见this regex debugger step by step查看正在运行的正则表达式。

关于regex - Postgres 中的非贪婪捕获组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60253290/

相关文章:

java FilenameFilter 正则表达式(向前看)

python - 根据某些条件从不同的 pyspark 列中提取所有匹配项

正则表达式将每个偶数字符转换为大写 - Notepad++

.net - 正则表达式匹配

postgresql - 默认的 PostgreSQL 密码加密方法

java - PostgreSQL JDBC 驱动程序不适用于 Heroku 数据库连接

javascript - JavaScript 中的环视替代方案

php - 用逗号分割,后面不跟小写字母

javascript - 使用正则表达式替换函数调用

postgresql - 从 Heroku Postgres 导出备份