【问题标题】:How to extract an undefined length of a string in Postgres如何在 Postgres 中提取未定义长度的字符串
【发布时间】:2014-05-26 11:35:58
【问题描述】:

我是 sql 的新手,我想从以下字符串中提取“SWAMP RIVER NEAR DOVER PLAINS NY”:

<a href='http://waterdata.usgs.gov/nwis/nwisman/?site_no=01199490'>01199490</a> SWAMP RIVER NEAR DOVER PLAINS NY</a>

问题是我要提取的范围的长度在每一行中都不同。

我尝试了以下方法:

select substring (name, 80 , char_length(name) - 4 ) from stream_gages; 

但我得到:SWAMP RIVER NEAR DOVER PLAINS NY&lt;/a&gt; 不管我在减号后面放什么数字。

有什么办法可以做到吗?

所以,我真正想做的是将每个流计量站的代码和名称提取到新列中,包含在:

&lt;a href='http://waterdata.usgs.gov/nwis/nwisman/?site_no=01199490'&gt;01199490&lt;/a&gt; SWAMP RIVER NEAR DOVER PLAINS NY&lt;/a&gt;

为了做一些 GIS 查询。

代码是从位置 57 开始的数字,从位置 80 开始的名称(在大多数情况下代码长度不变的情况下)但是名称的长度在每一行中都不同。代码的长度也在几行中有所不同,但如果很难想出一个执行此操作的 sql,我可以手动编辑它。但是,对于所有 240 行中的名称,长度是不同的。谢谢。

【问题讨论】:

  • 第三个参数是要提取的子串的长度,不是结束位置
  • 您确定不想使用外部 HTML 解析器吗?
  • 如果是length of the range I want to extract varies in each row,显然你需要指定如何它的变化。请举例或更多解释。
  • 感谢您的澄清。 @ClodoaldoNeto 我对 JS 和 SQL 很陌生,以至于我不确定 HTML 解析器是什么。所以,是的。长度根据站名的长度而有所不同,但我知道每个站名都从位置 80 开始,并在位置 80 之后的第一个字符“

标签: postgresql substring undefined string-length


【解决方案1】:

你可以使用 regexp_replace() ,避免文字常量:

create TABLE bla
        ( id SERIAL NOT NULL PRIMARY KEY
        , body varchar
        );

select * from bla;

INSERT INTO bla(body) VALUES
(e'<a href=\'http://waterdata.usgs.gov/nwis/nwisman/?site_no=01199490\'>01199490</a> SWAMP RIVER NEAR DOVER PLAINS NY</a>' )
        ;

select id
  , regexp_replace(body, e'.+<\/a> ([^<]+)<\/a>.*', '\1')
from bla;

结果:

CREATE TABLE
 id | body 
----+------
(0 rows)

INSERT 0 1
 id |          regexp_replace          
----+----------------------------------
  1 | SWAMP RIVER NEAR DOVER PLAINS NY
(1 row)

【讨论】:

  • 感谢您的回答。它适用于这一特定行,但不适用于所有行:"> 多佛平原附近的沼泽河"">盖洛德斯维尔附近的泰米尔河"">盲溪在 RYE NY" "> BEAVER SWAMP BROOK 在 MAMARONE" "> Hutchinson RIVER 在 PELHAM NY
  • 好吧,我只能回答已经提出的问题,不是吗?如果你有不同的行,其中有不同的模式,也许可以使用另一个正则表达式。 (或者可能是完全不同的解决方案)
  • 当然,您提出的解决方案适用于原始问题中的问题。直到我意识到我的问题并不清楚,然后我才编辑了我的问题。非常感谢您的回答和时间。我是钢铁试图弄清楚这一点。再次感谢您。
  • 您好,这里再说一次,实际上提出的解决方案是有效的。我只是在输入代码时犯了一个愚蠢的小错误。如果您不介意,请解释一下您为什么输入您输入的参数,以便我可以将其应用于其他情况?
  • 我不能也(不应该)在一个答案或评论中向您解释正则表达式。阅读它们(也许在我链接的手册中)。基本上,这个特殊的正则表达式由三部分组成:你想要的东西([^&lt;]+) 以及'.+&lt;\/a&gt; 之前和&lt;\/a&gt;.*' 它之后的所有内容。第三个参数中的\1 引用了括号中的部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-19
  • 2019-06-25
  • 2022-01-04
  • 2022-11-14
相关资源
最近更新 更多