Regex 如何从Mercurial/TortoiseHG'中排除文件夹列表;s.hg文件?

Regex 如何从Mercurial/TortoiseHG'中排除文件夹列表;s.hg文件?,regex,mercurial,tortoisehg,Regex,Mercurial,Tortoisehg,嗯。我需要忽略版本控制中的文件列表,除了三个特定文件夹中的文件(我们称它们为Folder1、Folder2和Folder3)。我可以列出我需要忽略的所有文件夹作为一个简单的列表,但我认为这不是一个优雅的方式,所以我写了下面的正则表达式: .*/(Bin|bin)/(?!Folder1/|Folder2/|Folder3/).* 我的想法如下,从左到右: .*-任意数量的任意字符 /-斜杠符号,用于将文件夹彼此分开 (Bin | Bin)-具有“Bin”或“Bin”名称的文件夹 /-斜杠符号,

嗯。我需要忽略版本控制中的文件列表,除了三个特定文件夹中的文件(我们称它们为Folder1、Folder2和Folder3)。我可以列出我需要忽略的所有文件夹作为一个简单的列表,但我认为这不是一个优雅的方式,所以我写了下面的正则表达式:

.*/(Bin|bin)/(?!Folder1/|Folder2/|Folder3/).*
我的想法如下,从左到右:

  • .*-任意数量的任意字符
  • /-斜杠符号,用于将文件夹彼此分开
  • (Bin | Bin)-具有“Bin”或“Bin”名称的文件夹
  • /-斜杠符号,用于将文件夹彼此分开
  • (?!Folder1/| Folder2/| Folder3/)-文件夹名称不是“Folder1/”,也不是“Folder2/”,也不是“Folder3/”。这部分是最复杂的,但我还是用谷歌搜索了一下。我不明白为什么它应该工作,但它在测试期间工作
  • .*-任意数量的任意字符
当我在regex101.com上使用两个文本字符串(表示文件路径)对该表达式进行测试时,该表达式非常有效,但当我将其放入.hgignore文件时,该表达式无效,如下所示:

syntax: regexp
.*/(Bin|bin)/(?!Folder1/|Folder2/|Folder3/).*
出于某种原因,它会忽略所有“Bin”和“Bin”文件夹中的所有文件和子文件夹。我怎样才能完成我的任务

另外,据我所知,Mercurial/TortoiseHG使用Python/Perl正则表达式


非常感谢。

为了使问题更清楚一点(至少对我来说),我们有很多应该忽略的
/bin/somename/…
../bin/anothername/…
名称,以及三组
../bin/folder1/…
../bin/2folder/…
,和
../Bin/third/…
一组不应忽略的名称

因此,我们需要一个正则表达式(没有锚定)来匹配要忽略的名称,而不是要保留的名称。(此外,glob匹配不起作用,因为它没有那么强大:我们要么匹配得太少,要么匹配得太多,而Mercurial缺少Git的“override with later un ignore”特性。)

最短的正则表达式应为:

/[Bb]in/(?!(folder1 | 2folder | third)/)
(此正则表达式中与字符串(如
/bin/somename/…
匹配的部分只是
/bin/
部分,但Mercurial不查看匹配的内容,只查看匹配的内容。)

问题是,您的示例正则表达式应该可以工作,它只是同一事物的一个较长变体,不需要,但无害(性能除外)
*
添加在前面和后面。因此,如果你的不起作用,上述方法也可能不起作用。一个带有一些虚拟文件的示例存储库,可以对其进行克隆和实验,这将有助于诊断问题


(对非问题的)原始(错误)答案 所需情况的最短正则表达式为:

/Folder[123]中的
/[Bb]/
但是,如果目录/文件夹名称实际上不符合这种模式,我们需要:

/[Bb]in/(somedir |另一个|第三个)/
解释 首先,附带说明:默认语法是regexp,因此不需要初始的
语法:regexp
行。因此,您的
.hgignore
文件可能不是正确的UTF-8格式:请参阅。(但这会产生不同的行为,所以这可能是一个问题。在任何关于
.hgignore
文件故障的回答中都值得一提。)

接下来,值得注意的是以下几点:

  • Mercurial只跟踪文件,不跟踪目录/文件夹。因此,真正的问题是任何给定的文件名是否与
    .hgignore
    中列出的模式匹配。如果它们确实匹配,并且该文件当前未跟踪,则不会通过“添加所有内容”操作自动添加该文件,Mercurial也不会抱怨该文件未跟踪

  • 如果某个文件已经被跟踪,那么其名称与忽略模式匹配的事实就无关紧要了。如果文件
    a/b/c.ext
    未被跟踪且与模式匹配,
    hg add a/b/c.ext
    仍将添加它,而
    hg add a/b
    将总体添加
    a/b
    中的所有内容,但不会添加
    c.ext
    ,因为它与模式匹配。因此,重要的是要知道文件是否已经被跟踪,并考虑您显式地列出了什么?例如,另见

  • Glob模式比正则表达式更容易正确编写。除非你这样做是为了学习或教学,或者glob功能不够强大,否则请坚持使用glob模式。(在非常旧的Mercurial版本中,glob匹配明显比regexp匹配慢,但这已经被修复了很长一段时间。)

  • Mercurial的regexp ignore条目不会自动锚定:如果希望锚定行为,请根据需要在前端使用
    ^
    ,在末尾使用
    $
    。在这里,您不需要锚定行为,因此可以消除前导和尾随的
    *
    。(Mercurial将其称为根模式而不是锚定模式,需要注意的是,有些模式是锚定模式,但
    .hgignore
    模式不是。)

  • Python/Perl regexp
    (?!…)
    语法是否定语法:
    (?!…)
    如果括号中的表达式与字符串不匹配,则匹配。这是问题的一部分

  • 我们不必担心捕获组(请参阅),因为Mercurial对来自正则表达式的组不做任何处理。它只在乎我们是否匹配

  • 路径名实际上是斜杠分隔的组件。主要组件是文件名上方的各种目录(文件夹),最后一个组件是文件名。(也就是说,尽量不要把第一部分看作文件夹:这不是因为它错了,而是因为它没有“组件”那么一般,因为