Postgres正则表达式从路径获取子串

时间:2012-10-26 03:28:49

标签: regex postgresql

我需要从路径目录中获取一个由2个数字组成的子字符串,然后是“_”。字符串就像:

'P:\pgdfecol\71698384737978\INFENTECONTROL\2011_9_43\2011_9_46_43_29_10.ZIP'

在这种情况下,我希望在46之后得到43。

在最后一个反斜杠之后,路径存储在下一个规则之后:

'\TablesPK_twoCharactersClassification_twoCharactersDocumentType_anything.ZIP'

我想获得分类。问题是表的主键可能不止一个字段,虽然我知道每个字段中有多少字段。

我得到了类似的东西:

select substring(substring(substring('P:\pgdfecol\71698384737978\INFENTECONTROL\2011_9_43\2011_9_46_43_29_10.ZIP' from '([^\\]*(\.ZIP|zip))') from '([^_]*_){4}') from '[0-9]{2}')

但我想要更简单的东西。

其他情况:

'P:\pgdfecol\71698384737978\INFENTECONTROL\2011_03_46\2011_03_46_46_48_.ZIP'

(需要第二个46)

'P:\pgdfecol\71698384737978\INFCONTABLE\2009_05_INBP\2009_05_INBP_22_28_.ZIP'

(在INBP之后需要22)

'P:\pgdfecol\71698384737978\INFOFICIAL\2007_06_MB\2007_06_MB_29_28_.ZIP'

(需要29)

'P:\pgdfecol\71698384737978\ASOCIADOS\8010625\8010625_02_04_20110111.ZIP'

(8010625之后的02)

在最后一种情况下,pk只是一个字段,所以我把句子更改为:

select substring(substring(substring('P:\pgdfecol\71698384737978\ASOCIADOS\8010625\8010625_02_04_20110111.ZIP' from '([^\\]*(\.ZIP|zip))') from '([^_]*_){2}') from '[0-9]{2}')

对于一个Pk,我需要第二组([^_]*_),第三组为第四组,依此类推......

select substring(substring(substring('P:\pgdfecol\71698384737978\ACTASCOMITE\ACRE123\ACRE123_17_11_.ZIP' from '([^\\]*(\.ZIP|zip))') from '([^_]*_){2}') from '[0-9]{2}')

(我17岁)

我正在使用postgres 9.0。

1 个答案:

答案 0 :(得分:2)

我开始明白了。考虑这个测试用例:

WITH x(txt) AS ( VALUES
     ('P:\pgdfecol\71698384737978\INFENTECONTROL\2011_9_43\2011_9_46_43_29_10.ZIP')  -- 43
    ,('P:\pgdfecol\71698384737978\INFENTECONTROL\2011_03_46\2011_03_46_46_48_.ZIP')  --need the second 46
    ,('P:\pgdfecol\71698384737978\INFCONTABLE\2009_05_INBP\2009_05_INBP_22_28_.ZIP') --need the 22 after INBP
    ,('P:\pgdfecol\71698384737978\INFOFICIAL\2007_06_MB\2007_06_MB_29_28_.ZIP')      --need the 29
    )
SELECT txt, substring(txt, '\\(?:[^_\\]+_){3}(\d\d)_[^\\]*\.(?:ZIP|zip)$')
FROM   x

(?:) ..非捕获括号
[^_\\] ..包含除\_以外的任何字符的字符类 \d ..一个数字,与[0-9]有效相同 + ..一场或多场比赛(贪婪)
$ ..字符串的结尾
[_\d] ..包含数字和_

的字符类

只有一个pk的情况需要不同的模式。使用{1}代替{3}

不确定为什么要逃避反斜杠。在PostgreSQL的现代版本standard_conforming_strings默认为on,因此您不需要在字符串中转义反斜杠 - 但当然仍然是正则表达式。