【问题标题】:Notepad++ regex group captureNotepad++ 正则表达式组捕获
【发布时间】:2013-07-01 22:12:27
【问题描述】:

我有这样的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

【问题讨论】:

    标签: regex notepad++


    【解决方案1】:

    这无需环顾四周:

    查找:[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 个句点的主机名,然后将其替换为第一个点之后的所有内容。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:
        .+?\.([\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))$

        【讨论】:

          【解决方案4】:

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

          看上图,正则表达式捕获指的是什么
          它的颜色就像你不再需要正则表达式解释一样......

          【讨论】:

            猜你喜欢
            • 2012-01-02
            • 2013-06-27
            • 1970-01-01
            • 2018-03-11
            • 1970-01-01
            • 1970-01-01
            • 2015-07-24
            相关资源
            最近更新 更多