Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在.hgignore中模拟语言补码运算符?_Python_Regex_Mercurial - Fatal编程技术网

Python 如何在.hgignore中模拟语言补码运算符?

Python 如何在.hgignore中模拟语言补码运算符?,python,regex,mercurial,Python,Regex,Mercurial,我有一个与一组文件名匹配的Python正则表达式。如何更改它,以便在Mercurial的.hgignore文件中使用它来忽略与表达式不匹配的文件 完整故事: 我有一个很大的源代码树,其中的*.ml文件散布在各处。我想把它们放到一个新的存储库中。还有其他不太重要的文件,它们太重,无法包含在存储库中。我试图找到.hgignore文件的对应表达式 第一个观察:Python没有常规的语言补码操作符(AFAIK,它只能补码一组字符)。(顺便说一句,为什么?) 第二项观察: Python中的以下正则表达式:

我有一个与一组文件名匹配的Python正则表达式。如何更改它,以便在Mercurial的.hgignore文件中使用它来忽略与表达式不匹配的文件

完整故事: 我有一个很大的源代码树,其中的
*.ml
文件散布在各处。我想把它们放到一个新的存储库中。还有其他不太重要的文件,它们太重,无法包含在存储库中。我试图找到
.hgignore
文件的对应表达式

第一个观察:Python没有常规的语言补码操作符(AFAIK,它只能补码一组字符)。(顺便说一句,为什么?)

第二项观察: Python中的以下正则表达式:

re.compile("^.*(?<!\.ml)$")
但是,当我在
.hgignore
文件中放入完全相同的表达式时,我得到以下结果:

$ hg st --all  
?  abc.ml  
I .hgignore  
I abcabc  
I x/xabc  
I x/xabc.ml  
根据
.hgignore
手册页,Mercurial只使用普通的Python正则表达式。那我怎么会得到不同的结果呢? Mercurial怎么可能找到与
x/xabc.ml
匹配的文件


有人知道缺少常规语言补码运算符的不那么难看的方法吗?

通过一些测试,找到了两种似乎有效的解决方案。第一个根指向一个子目录,显然这很重要。第二个是脆弱的,因为它只允许使用一个后缀。我正在使用Mercurial 1.2.1在Windows XP(定制为更加unixy)上运行这些测试

(我用
#消息
添加了评论。)

$hg--版本 Mercurial分布式SCM(版本1.2.1) $cat.hg忽略 语法:regexp ^x/+(?)? 第二点:

$ cat .hgignore syntax: regexp #^x/.+(?<!\.ml)$ ^.+[^.][^m][^l]$ # brittle, can only use one suffix $ hg status --all ? abc.ml # versioned, is *.ml ? x\saveme.ml # versioned, is *.ml I .hgignore # ignored, is not *.ml I abcabc # ignored, is not *.ml I x\abcabc # ignored, is not *.ml I x\ignoreme.txt # ignored, is not *.ml $cat.hg忽略 语法:regexp #^x/+(?)?
根据我对OP的理解,第二个具有完全预期的行为。第一个仅在子目录中具有预期的行为,但更灵活。

问题在于子目录中的匹配项与根目录中的匹配项不同。请注意以下几点:

$ hg --version
Mercurial Distributed SCM (version 1.1.2)
它是旧版本,但其行为方式相同。我的项目包含以下文件:

$ find . -name 'abc*' -print
./x/abcabc
./x/abc.ml
./abcabc
./abc.ml
这是我的.hgignore:

$ cat .hgignore
^.*(?<!\.ml)$
因此,
hg
无法拾取
x/abc.ml
。但这真的是正则表达式的问题吗?也许不是:

$ python
Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41) 
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mercurial.ignore
>>> import os
>>> root = os.getcwd()
>>> ignorefunc = mercurial.ignore.ignore(root, ['.hgignore'], lambda msg: None)
>>> 
>>> ignorefunc("abc.ml") # No match - this is correct
>>> ignorefunc("abcabc") # Match - this is correct, we want to ignore this
<_sre.SRE_Match object at 0xb7c765d0>
>>> ignorefunc("abcabc").span() 
(0, 6)
>>> ignorefunc("x/abcabc").span() # Match - this is correct, we want to ignore this
(0, 8)
>>> ignorefunc("x/abc.ml") # No match - this is correct!
>>> 
$python
Python 2.6.2(Release26Maint,2009年4月19日,01:56:41)
[GCC 4.3.3]关于linux2
有关详细信息,请键入“帮助”、“版权”、“信用证”或“许可证”。
>>>导入mercurial.ignore
>>>导入操作系统
>>>root=os.getcwd()
>>>ignorefunc=mercurial.ignore.ignore(根,['.hgignore'],lambda msg:None)
>>> 
>>>ignorefunc(“abc.ml”)#不匹配-这是正确的
>>>ignorefunc(“abcabc”)#匹配-这是正确的,我们希望忽略这一点
>>>ignorefunc(“abcabc”).span()
(0, 6)
>>>ignorefunc(“x/abcabc”).span()#匹配-这是正确的,我们希望忽略这一点
(0, 8)
>>>ignorefunc(“x/abc.ml”)#不匹配-这是正确的!
>>> 
请注意,
ignorefunc
treated
abcabc
x/abcabc
是相同的(匹配-即忽略),而
abc.ml
x/abc.ml
也是相同的(不匹配-即不忽略)


因此,也许逻辑错误在Mercurial中的其他地方,或者我看到的Mercurial的错误部分(如果是这样的话,我会感到惊讶)。除非我遗漏了什么,可能是一个bug(而不是Martin Geisler指出的RFE)需要针对Mercurial进行归档。

正则表达式依次应用于每个子目录组件以及文件名,而不是一次应用于整个相对路径。因此,如果我的回购协议中有a/b/c/d,则每个正则表达式将应用于a、a/b、a/b/c以及a/b/c/d。如果任何组件匹配,则将忽略该文件。(您可以通过使用bar/foo尝试
^bar$
来判断这是一种行为-您将看到bar/foo被忽略。)

^.*(*忽略x/xabc.ml,因为模式匹配x(即子目录)


这意味着没有正则表达式可以帮助您,因为您的模式必须与第一个子目录组件匹配。

您应该去订阅此错误报告:如果您对我的第一个答案做出响应,当我从^re/+更改为^re.+(如问题所示)时,我能够重现该问题。(因此我删除了该答案。)显然,这与指定的目录有关,这导致我提出了当前的建议。我没有查看hg的源代码,但是,根据这个外部测试,问题确实存在。呃-是的,我是在评论你的第一个(现在已删除)回答。无论如何,我的测试似乎没有指出正则表达式是问题的根源。不幸的是,如果我在.hgignore中尝试您的模式,我会看到以下内容显示为“?”:.hgignore(不应该存在)、abc.ml(应该存在)、abcabc(不应该存在)、x/abc.ml(应该存在)、y/abc.ml(应该存在)、y/abcabc.ml(不应该存在)。对于OP的正则表达式,它正确地忽略了所有内容,但也错误地忽略了x/abc.ml和y/abc.ml。因此,我不确定这是否是一种解决方法。哪种模式?以子目录为根的模式(第一种)当然不会影响不在该子目录中的文件。除了一个警告,它在所有情况下都会正常工作,第二个也会正常工作。我现在就更新我的帖子。我指的是第一个,因为它没有被注释掉。然而,不幸的是,你上面的脆弱re也不能用于文件名,这也是为什么会这样的另一个原因脆性。:)感谢您找到了这个额外的错误。第一个解决方案需要在.hgignore中指定所有目录。这归结为使用手工工具对源代码树进行爬网(然后我们可以显式选择每个文件,并且不需要.hgignore)。第二个正则表达式导致包含名为“shame”的文件(不匹配)。这太不准确了。但在我上面的回答中,“x/abcabc”和“x/abc.ml”被区别对待:第一个匹配(正确),而第二个不匹配(也正确)。您正在应用
$ cat .hgignore
^.*(?<!\.ml)$
$ hg stat
? abc.ml
$ python
Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41) 
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mercurial.ignore
>>> import os
>>> root = os.getcwd()
>>> ignorefunc = mercurial.ignore.ignore(root, ['.hgignore'], lambda msg: None)
>>> 
>>> ignorefunc("abc.ml") # No match - this is correct
>>> ignorefunc("abcabc") # Match - this is correct, we want to ignore this
<_sre.SRE_Match object at 0xb7c765d0>
>>> ignorefunc("abcabc").span() 
(0, 6)
>>> ignorefunc("x/abcabc").span() # Match - this is correct, we want to ignore this
(0, 8)
>>> ignorefunc("x/abc.ml") # No match - this is correct!
>>>