使用(意外)转义字符传递字符串即使它是原始字符串也会丢失字符

时间:2010-04-05 19:36:38

标签: python regex escaping doctest rawstring

我有一个python doctest的函数失败,因为其中一个测试输入字符串有一个反斜杠被视为转义字符,即使我已将字符串编码为原始字符串。

我的doctest看起来像这样:

>>> infile = [ "Todo:        fix me", "/** todo: fix", "* me", "*/", r"""//\todo      stuff to fix""", "TODO fix me too", "toDo bug 4663" ]
>>> find_todos( infile )
['fix me', 'fix', 'stuff to fix', 'fix me too', 'bug 4663']

该函数旨在通过todo规范的某些变化从单行中提取待办事项文本,如下所示:

todos = list()
for line in infile:
    print line
    if todo_match_obj.search( line ):
        todos.append( todo_match_obj.search( line ).group( 'todo' ) )

名为todo_match_obj的正则表达式为:

r"""(?:/{0,2}\**\s?todo):?\s*(?P<todo>.+)"""

与我的ipython shell快速对话给了我:

In [35]: print "//\todo"
//      odo

In [36]: print r"""//\todo"""
//\todo

并且,以防doctest实现使用stdout(我没有检查,抱歉):

In [37]: sys.stdout.write( r"""//\todo""" )
//\todo

我的正则表达式并不高于任何标准,我意识到我可能会遗漏一些东西。

编辑:在Alex Martellis回答之后,我想了解正则表达式 与爆破r"""//\todo fix me"""实际匹配的建议。我知道我原本没有要求别人做我的作业,我会接受亚历克斯的回答,因为它确实回答了我的问题(或证实了我的恐惧)。但我承诺在这里为我的问题提出任何好的解决方案:)

EDITEDIT:作为参考,已经向kodos项目提交了一个错误:bug #437633

我正在使用Python 2.6.4(r264:75706,2009年12月7日,18:45:15)

感谢您阅读此内容(如果您直接跳到这里,我明白了)

2 个答案:

答案 0 :(得分:2)

仔细阅读原始正则表达式:

r"""(?:/{0,2}\**\s?todo):?\s*(?P<todo>.+)"""

它匹配:零到两个斜杠,然后是0 +星,然后是0或1个“空格字符”(空格,制表符等),然后是文字字符'todo'(依此类推)。

你的rawstring是:

r"""//\todo      stuff to fix"""

所以斜杠和'todo'之间有一个字面反斜杠,因此当然正则表达式与它不匹配。它不能 - 在正则表达式中没有任何地方表达任何可选地匹配字面反斜杠的愿望。

修改: 一个非常接近你的RE模式,接受并忽略't'之前的可选反斜杠:

r"""(?:/{0,2}\**\s?\\?todo):?\s*(?P<todo>.+)"""

请注意反斜杠 必须重复,以“逃避自己”,在这种情况下。

答案 1 :(得分:1)

当我冒险进入doctests的道路时,这变得更加奇怪。

考虑这个python script

如果取消注释第22行和第23行,脚本就会正常传递,因为该方法会返回True,它会被声明并显式比较。

但是如果你在链接中运行文件,doctest将失败并显示消息:

% python doctest_test.py                                                                                                          
**********************************************************************
File "doctest_test.py", line 3, in __main__.doctest_test
Failed example:
    doctest_test( r"""//    odo""" )
Exception raised:
    Traceback (most recent call last):
      File "/usr/lib/python2.6/doctest.py", line 1241, in __run
        compileflags, 1) in test.globs
      File "<doctest __main__.doctest_test[0]>", line 1, in <module>
        doctest_test( r"""//    odo""" )
      File "doctest_test.py", line 14, in doctest_test
        assert input_string == compare_string
    AssertionError
**********************************************************************
1 items had failures:
   1 of   1 in __main__.doctest_test
***Test Failed*** 1 failures.

有人可以在这里启发我吗?

我还在使用python 2.6.4。

我将这个答案放在“社区维基”下,因为它确实没有声誉与问题有关。