58

我有这样的txt文件:

ххх.prontube.ru
salo.ru
bbb.antichat.ru
yyy.ru
xx.bb.prontube.ru
zzz.com
srfsf.jwbefw.com.ua

尝试使用此类正则表达式删除所有子域:

Find:    .+\.((.*?)\.(ru|ua|com\.ua|com|net|info))$
Replace with: \1

收到:

prontube.ru
salo.ru
antichat.ru
yyy.ru
prontube.ru
zzz.com
com.ua

为什么最后一行变成com.ua而不是jwbefw.com.ua

4

4 回答 4

62

这无需环顾四周:

查找:[a-zA-Z0-9-.]+\.([a-zA-Z0-9-]+)\.([a-zA-Z0-9-]+)$ 替换:\1\.\2

它会找到至少有 2 个句点并且在最后两个句点后面只有字母、数字和破折号的东西;然后它用最后两个部分替换它。在我看来,更直观。

那个领导有一些有趣的事情发生xxx。它似乎不是纯 ASCII。为了这个问题,我假设这只是这个网站的有趣之处,并不代表您的真实数据。

不正确

有趣的是,我之前在这里有一个不正确的答案,积累了很多赞成票。所以我认为我应该保留它:

查找:[a-zA-Z0-9-]+\.([a-zA-Z0-9-]+)\.(.+)$ 替换:\1\.\2

它只是找到一个至少包含 2 个句点的主机名,然后用第一个点之后的所有内容替换它。

于 2013-07-01T23:30:25.333 回答
10

.+零件尽可能匹配。尝试.+?改用,它将捕获尽可能少的内容,从而允许com.ua选项匹配。

于 2013-07-01T22:14:04.360 回答
1
.+?\.([\w-]*?\.(?:ru|ua|com\.ua|com|net|info))$

这个答案仍然使用原始问题正在查看的特定域名。由于某些 TLD(顶级域)中有一个句点,理论上您可以拥有一个包含多个子域的列表,如果它适用于您的数据集,则在正则表达式中将 TLD 列入白名单是一个好主意。当前的两个答案(从 2013 年开始)都无法正确处理“xx.bb.prontube.ru”和“srfsf.jwbefw.com.ua”之间的区别。

下面是为什么这个 psnig 的原始正则表达式没有按预期工作的快速解释:
+是贪婪的。 .+将在捕获所有内容的行尾一直拉到右边,然后向后(向左)从这里寻找匹配项:

(ru|ua|com\.ua|com|net|info)

使用srfsf.jwbefw.com.ua正则表达式引擎将首先失败匹配a,然后它将标记向左移动一个位置以查看“ua”此时,ua正则表达式(第二个选项)是匹配的。

引擎不会继续寻找“com.ua”,因为“.ua”满足了该要求。

Niet the Dark Absol 的回答告诉正则表达式“懒惰”
.+?将匹配任何字符(至少一个),然后尝试找到正则表达式的下一部分。如果失败,它将推进令牌,.+再匹配一个字符,然后再次评估正则表达式的其余部分。
.+? 最终将消耗:srfsf.jwbefw在匹配句点之前,然后匹配com.ua

但是, 的实施?也会产生问题。

添加问号会首先使 .+ 变得懒惰,但随后会导致 group1 匹配bb.prontube.ru而不是prontube.ru

这是因为 bb 之后的第一个时期将匹配,然后在第 1 组内(.*?)将匹配bb.prontube\.(ru|ua|com\.ua|com|net|info))$比赛前.ru

为避免这种情况,请将第三组从 更改为(.*?)([\w-]*?) 这样它就不会捕获只有字母和数字,或破折号。

结果正则表达式:
.+?\.(([\w-])*?\.(ru|ua|com\.ua|com|net|info))$

请注意,您不需要捕获除第一个之外的任何组。添加 ?: 使 TLD 选项不被捕获。

最后一次变更:
.+?\.([\w-]*?\.(?:ru|ua|com\.ua|com|net|info))$

于 2019-08-21T20:09:10.600 回答
1

搜索内容:.+?\.(\w+\.(?:ru|com|com\.au))
替换为:$1

看上面的图片,什么正则表达式捕获指的是
它的颜色,你将不再需要正则表达式解释......

在此处输入图像描述

于 2021-02-24T10:25:57.613 回答