PostgreSQL中截取字符串至倒数第二个下划线前的内容
PostgreSQL 截取字符串到倒数第二个下划线前的解决方案
直接用正则表达式结合substring或regexp_replace就能搞定,不用折腾reverse和strpos的嵌套逻辑,更灵活通用。
方法1:使用substring捕获目标内容
核心思路是用正则捕获开头到倒数第二个下划线之前的所有内容,忽略最后两个下划线及其后续部分(包括扩展名)。
SQL示例:
SELECT substring(your_column_name from '^(.*)_[^_]+_[^_]+(\..*)?$') AS extracted_part FROM your_table;
测试示例:
SELECT substring('SEALS_LME_TRADES_MBL_20220919_00212.csv' from '^(.*)_[^_]+_[^_]+(\..*)?$'); -- 返回结果:SEALS_LME_TRADES_MBL
正则含义拆解:
^:锚定字符串开头(.*):捕获任意字符(尽可能多),直到遇到后续的下划线模式_[^_]+:匹配一个下划线,后跟至少一个非下划线字符(对应倒数第二个下划线后的日期部分)_[^_]+:再匹配一组下划线+非下划线字符(对应倒数第一个下划线后的序号部分)(\..*)?$:可选匹配文件扩展名(点+任意字符),确保兼容有无扩展名的情况
方法2:使用regexp_replace替换冗余部分
把最后两个下划线及后面的所有内容替换为空,直接得到目标字符串:
SQL示例:
SELECT regexp_replace(your_column_name, '_[^_]+_[^_]+(\..*)?$', '') AS extracted_part FROM your_table;
测试示例:
SELECT regexp_replace('SEALS_LME_TRADES_MBL_20220919_00212.csv', '_[^_]+_[^_]+(\..*)?$', ''); -- 返回结果:SEALS_LME_TRADES_MBL
为什么你之前的正则不生效
你尝试的^(([^_]_){4})是固定匹配4组「非下划线+下划线」,只能处理目标部分恰好有4个下划线的情况。但如果目标字符串的下划线数量变化(比如多一个或少一个),这个正则就会失效。而上面的方案是动态定位倒数第二个下划线,不管前面有多少个下划线都能适用。
内容的提问来源于stack exchange,提问作者Achilles
相关产品推荐
相关产品推荐

