【问题标题】:Non-greedy match in vimvim中的非贪婪匹配
【发布时间】:2025-11-29 06:40:01
【问题描述】:

我在 Stack Overflow 中看到了一些关于它的问题,但仍然无法解决我的问题。我快到了,但需要一些帮助。 我试图找到的模式是:

/SELECT.*\ncoalesce.*\(\n.*\)*) x

这意味着: SELECT, 任何东西, 换行符, 合并, 任何东西, (换行符, 任何东西)*, ) x

问题是,模式“(换行符,任何东西)”应该出现 0 次或多次,但尽可能少,所以我尝试将 * 替换为 {-},将搜索变为

/SELECT.*\ncoalesce.*\(\n.*\)\{-}) x

但它没有用。它会根据我的需要不断选择一个大块而不是几个块。如果我使用数字而不是 -(例如 {10}),它适用于 10 行或更少行的块,但由于这个数字可能会有所不同,我不能这样做。 有没有人有办法解决吗? 下面是我正在使用的文件示例:

INSERT INTO lattes.palavras_chave (palavra_chave_1,palavra_chave_2,palavra_chave_3,palavra_chave_4,palavra_chave_5,palavra_chave_6)
SELECT palavra_chave_1,palavra_chave_2,palavra_chave_3,palavra_chave_4,palavra_chave_5,palavra_chave_6 from (
SELECT
coalesce(T2.Loc.value('@PALAVRA-CHAVE-1','varchar(max)'),'') as palavra_chave_1 ,
coalesce(T2.Loc.value('@PALAVRA-CHAVE-2','varchar(max)'),'') as palavra_chave_2 ,
coalesce(T2.Loc.value('@PALAVRA-CHAVE-3','varchar(max)'),'') as palavra_chave_3 ,
coalesce(T2.Loc.value('@PALAVRA-CHAVE-4','varchar(max)'),'') as palavra_chave_4 ,
coalesce(T2.Loc.value('@PALAVRA-CHAVE-5','varchar(max)'),'') as palavra_chave_5 ,
coalesce(T2.Loc.value('@PALAVRA-CHAVE-6','varchar(max)'),'') as palavra_chave_6
,tx.data_modificacao as data_modificacao_xml
FROM lattes.curriculos_xml tx
CROSS APPLY arquivo.nodes('//PALAVRAS-CHAVE') as T2(Loc)
) x
group by 
palavra_chave_1,
palavra_chave_2,
palavra_chave_3,
palavra_chave_4,
palavra_chave_5,
palavra_chave_6;

INSERT INTO lattes.area_do_conhecimento_1 (nome_grande_area_do_conhecimento,nome_da_area_do_conhecimento,nome_da_sub_area_do_conhecimento,nome_da_especialidade)
SELECT nome_grande_area_do_conhecimento,nome_da_area_do_conhecimento,nome_da_sub_area_do_conhecimento,nome_da_especialidade from (
SELECT
coalesce(T2.Loc.value('@NOME-GRANDE-AREA-DO-CONHECIMENTO','varchar(max)'),'') as nome_grande_area_do_conhecimento ,
coalesce(T2.Loc.value('@NOME-DA-AREA-DO-CONHECIMENTO','varchar(max)'),'') as nome_da_area_do_conhecimento ,
coalesce(T2.Loc.value('@NOME-DA-SUB-AREA-DO-CONHECIMENTO','varchar(max)'),'') as nome_da_sub_area_do_conhecimento ,
coalesce(T2.Loc.value('@NOME-DA-ESPECIALIDADE','varchar(max)'),'') as nome_da_especialidade
,tx.data_modificacao as data_modificacao_xml
FROM lattes.curriculos_xml tx
CROSS APPLY arquivo.nodes('//AREA-DO-CONHECIMENTO-1') as T2(Loc)
) x
group by 
nome_grande_area_do_conhecimento,
nome_da_area_do_conhecimento,
nome_da_sub_area_do_conhecimento,
nome_da_especialidade;

谢谢。

【问题讨论】:

    标签: regex vim regex-greedy


    【解决方案1】:

    请注意,即使使用\{-\},您的组中仍然有贪婪的.*

    试试select.*\ncoalesce\_.\{-\}\n) x

    【讨论】:

    • 哈!完美的!我以为\{-} 只考虑\(\n.*\) 之前的模式,但它正在考虑一切? \{-\}\{-} 一样吗?它在这里以两种方式起作用,只是为了让我清楚。
    • 是的,虽然不是必需的,但我更喜欢转义结束 } 以与开口保持一致。在:help non-greedy 下有一行提到这一点
    • 是的。我已经看到了帮助,但没有注意到关于反斜杠的最终评论。谢谢你的回答!
    【解决方案2】:

    问题是您的\n.*.* 在您的捕获组中是贪婪的。您可以通过切换到最后匹配您的\n 来克服这个问题,如下所示:

    /SELECT.*\ncoalesce.*\n\(.*\n\)\{-}) x
    

    或者使用两个\{-}:

    /SELECT.*\ncoalesce.*\(\n.\{-}\)\{-}) x
    

    或者通过将其替换为\_. 来简化您的捕获组(我的建议):

    /SELECT.*\ncoalesce\_.\{-}) x
    

    如需更多帮助,请参阅:

    :h /\_.
    :h /\{-
    

    【讨论】:

    • 很好的答案。谢谢!