正则表达式捕获开始于 \b 或结束 (www\.)

regex capturing to start at \b or end of (www\.)

我正在尝试从字符串中捕获任何看起来像域名的东西的首次出现。例如 'dfasdf https://www.my.domain.home.com fadsfas' 中的 my.domain.home.com。我正在使用 \b 断言或非捕获组 (?:www\.) 来标记捕获组的开始。但是我得到 www.my.domain.home.comwww. 没有被删除。

这是我的完整正则表达式:

\b(?:www\.)((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b

这是我不确定的部分:

\b(?:www\.)

如何让我的捕捉从单词的开头或 'www.' 的结尾开始?

[澄清] 如果没有 'www.' 它应该在单词的开头捕获。如果有 'www.',它应该在可能域字符串开头的 'www.' 中的点之后开始捕获。

我也用 https://www.regex101.com/r/NjR11m/1/tests 检查过它,但我的最终目标是 Teradata 15.10 正则表达式,据说它与 Perl 方言兼容。所以如果你能在 Perl 上下文中帮助我,我想我会没事的。

 SELECT 'dfasdf https://www.my.domain.home.com fadsfas' AS string, 
 REGEXP_SUBSTR(string, 
 '\b(?:www\.)((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b'
) AS url_to_match;

对于 'dfasdf https://my.domain.home.com fadsfas' 它也应该 return my.domain.home.com

字符串的其他示例也应该 return my.domain.home.com

'dfasdf my.domain.home.com fadsfas'

'dfasdf ,my.domain.home.com-- fadsfas'

'dfasdf www.my.domain.home.com#fadsfas'

[解决方案]

 REGEXP_SUBSTR(LOWER(string), 
 '\b(?!www\.)((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b'
 ) 

www. 被包含在匹配中的问题似乎是因为您使用的是第 0 组(这是完整匹配,而不仅仅是捕获组)。虽然我不知道如何更改它,但可以重新制定正则表达式,使第 0 组和第 1 组具有相同的值,如下所示:

\b(?!www\.)([-a-z0-9]{1,63}(?:\.[-a-z0-9]{1,63})+)

这只是说比赛不能从 www. 开始,而不是让比赛从那里开始然后不得不忽略它。

我已经制作了一个 modified version 你的正则表达式来展示它是如何工作的。请注意,如果你想匹配大小写混合的字母数字名称,你需要将 A-Z 添加到 a-z0-9 或打开不区分大小写;匹配非 ascii 域名需要更多的工作,留给感兴趣的 reader 去解决。