StringUtil indexOf()等效的PostgreSQL查询

5

我需要在PostgreSQL中实现stringUtils类的indexOf()方法。

假设我有一个,其中url是其中一列。

url: "http://paypal-info.com/home.webapps.cgi-bin-limit/webscr.cmd-login-submit"

我的要求是在上述URL中找到第3个'/'出现的位置,并在PostgreSQL查询中进行子字符串操作,只取paypal-info.com主机名。

有没有关于如何实现这个的想法将不胜感激。 谢谢。

3个回答

5
你尝试过使用split_part方法吗?
SELECT split_part('http://paypal-info.com/home.webapps.cgi-bin-limit/webscr.cmd-login-submit', '/', 3)

结果:

split_part
paypal-info.com

如果需要其他字符串函数,请参考此文档:http://www.postgresql.org/docs/9.1/static/functions-string.html

编辑:至于indexOf本身,我不知道是否有内置的postgres解决方案。但是使用两个字符串函数,您可以像这样实现:

SELECT strpos('http://paypal-info.com/home.webapps.cgi-bin-limit/webscr.cmd-login-submit', split_part('http://paypal-info.com/home.webapps.cgi-bin-limit/webscr.cmd-login-submit', '/', 4)) - 1 as index_of;

那看起来很棒,Michal。但是如何仅获取第三个 '/' 的 indexOf 而不进行分割。我的目标是获取索引?我们该怎么做? - Sri
@sri 抱歉,我关注了问题的这一部分:“在Postgresql查询中进行子字符串操作并仅获取paypal-info.com主机名”。因此,我已经取出了主机名。 至于查找第三个“/”出现的位置,我认为在postgres中没有简单的解决方案。您需要嵌套字符串函数。 - Michał Schielmann
@sri - 我已经编辑了答案,并提供了一些解决方法 - 不知道对你是否可行。 我使用了从上述split_part()函数中获取的第四个子字符串的位置。 - Michał Schielmann
@sri - 你可以将我编辑的这个解决方法封装到你自己的工具函数中,这样你就能得到你需要的结果了。 - Michał Schielmann

4

手册中的字符串函数和运算符部分相当于String.indexOf,例如。

select position('/' in 'http://paypal-info.com/home.webapps.cgi-bin-limit/webscr.cmd-login-submit');

然而,它并没有提供获取第n个出现次数的选项。
你的方法完全错误。你应该使用适当的URL解析代码来提取主机部分,而不是尝试自己编写或使用正则表达式/分割/字符串操作。
PostgreSQL没有本地的URL / URI类型,但其过程语言有,并且包装合适的函数非常简单。例如,使用PL / Python:
create language plpythonu;
create or replace function urlhost(url text) returns text 
language plpythonu 
immutable strict
as $$
import urlparse
return urlparse.urlparse(url).netloc
$$;

然后:
regress=# select urlhost('http://paypal-info.com/home.webapps.cgi-bin-limit/webscr.cmd-login-submit');
     urlhost     
-----------------
 paypal-info.com
(1 row)

如果您更喜欢使用PL/Perl、PL/V8或其他语言,都是可以的。
为了获得最佳性能,您可以编写一个简单的C函数并将其公开为扩展。

我不确定你对“错误”的定义是否正确。 - Vlad
@Vlad 嗯,这并不像使用正则表达式解析HTML那么糟糕,但是为什么要自己编写代码呢?你可以使用经过充分测试的预先编写好的代码。 - Craig Ringer
我是指这取决于具体的要求。 - Vlad
@Vlad PL/Perl或PL/Python是核心PostgreSQL分发的一部分。Python的“urlparse”是Python核心的一部分。在我看来,这是相当安全的赌注,如果真的有必要,您还可以回退到其他人已经提供的一些“split_part”解决方案中的一个。 - Craig Ringer

1

只需将3替换为N,即可获得给定字符串中第N个'/'的索引

SELECT length(substring('http://asd/asd', '(([^/]*/){3})')) - 1

要从url中提取主机名,您可以使用以下代码:

SELECT substring('http://asd.com:234/qwe', 'http://([^:]+).*/')

在此进行测试:SQLFiddle

(保留HTML)

抱歉 Vlad,这两个查询都不起作用。我不知道为什么。我没有得到任何输出。 - Sri
你的postgresql版本是什么? - Vlad
我还没有在数据库上测试过,等我有时间了再试试。 - Vlad
@sri 确实正则表达式有错误...现在已经更正了。还添加了一个 fiddle。 - Vlad
谢谢Vlad。第一个查询不需要-1,否则它会起作用。 - Sri
索引通常是从零开始的,这就是为什么要减1。如果你想让它从1开始,那么你确实不需要减1。顺便问一下,你的问题现在解决了吗? :) - Vlad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接