我正在尝试实现一个正则表达式来解析字符串的不同组。我提供的字符串表明客户想要将我们平台上的主要语言从 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/