【问题标题】:Regular expression to pad zeros正则表达式填充零
【发布时间】:2015-02-17 04:55:51
【问题描述】:

我的表中有一系列要订购的字符串。 例如。

Chapter 1 
Chapter 2 
Chapter 11 
Chapter 12

要正确订购它们,我需要用零填充它们。

Chapter 001 
Chapter 002 
Chapter 011 
Chapter 012

也许我可以使用 regexp_replace() 用正则表达式填充零。

  regexp_replace(chapters.name,'(\d+)\D*','0\1') as name

此解决方案不起作用。我想也许我可以计算出反向引用的长度并使用该数字来填充我需要的内容:

  regexp_replace(chapters.name,'(\d+)\D*',lpad('\l',3-length('\1'),'0') as name

length() 中的 \1 总是返回 2,尽管我注意到在某些 postgres 函数中使用 \1\1 转换为实际捕获的数据。

如何使用 Postgres 字符串函数和 Postgres 正则表达式填充零?

【问题讨论】:

    标签: sql regex postgresql natural-sort


    【解决方案1】:

    问题

    您的第二次尝试是两个误解的受害者:

    • lpad()rpad()的第二个参数是结果的总长度,而不是添加的字符数。

    • 您将regexp_replace() 的范围与lpad() 的范围混淆了。 lpad()先执行,\l\1lpad()没有特殊意义。

    解决方案

    这是“自然排序”的问题。相关答案:

    按照那里的建议,最好的解决方案是一开始就存储标准化数据。如果前导 'Chapter' 实际上是所有值中的不可变字符串,则根本不要存储它,只需将数字部分存储为 integer

    如果您的示例值是准确的,我们可以忽略前导常量文本并仅按尾随数字排序。比任何重新格式化字符串的尝试都快得多:

    SELECT *
    FROM   chapters
    ORDER  BY split_part(name, ' ', 2)::int
    

    如果您确实需要零填充字符串,并且前导文本可能会有所不同:

    SELECT split_part(name, ' ', 1) || ' '
        || lpad(split_part(name, ' ', 2), 3,  '0')
    FROM   chapters
    ORDER  BY 1;
    

    SQL Fiddle.

    两个函数调用加上串联,但仍然比regexp_replace() 快。正则表达式相对昂贵。
    lpad() 的更多示例:

    【讨论】:

    • 这让我走上了正确的道路。我拥有的数据不是很干净。有些行有多个空格。它也有3个字。我可以使用多个 split_parts,或子字符串或其他东西。反正我用过:select mapname, regexp_replace(mapname,'[ ]+[0-9].*',' ') || lpad(regexp_replace(mapname,'(.*)[ ]+([0-9].*)','\2'), 3, '0') from mapextents where maptype ~ 'grids' 这个"Map Index 94";"Map Index 094" "Map Index 95";"Map Index 095" "Map Index 100";"Map Index 100"
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-21
    • 2019-03-13
    • 2013-05-25
    • 2011-03-08
    • 1970-01-01
    • 1970-01-01
    • 2019-04-08
    相关资源
    最近更新 更多