当前的智慧: unicode / WinAnsiEncoding问题。re.compile(<rex>, re.DEBUG)帮了忙。
我试图使用python3.5模块PostScript匹配PDF (PostScript)“标准14”字体名。如果准备好接受| (而不是贪婪的),就像控制台窗口中的魅力:
Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:01:18) [MSC v.1900 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> standard14Names = (
... 'Times-Roman', 'Symbol',
... 'Times-(Bold)?(Italic)?', 'ZapfDingbats',
... '(Courier|Helvetica)-?(Bold)?(Oblique)?', # 'Helvetica-?(Bold)?(Oblique)?',
... 'Arial,?(Bold)?(Italic)?'
... )
>>> standard14 = re.compile("|".join(standard14Names))
>>> print(standard14.search("/Times-Roman"))
<_sre.SRE_Match object; span=(1, 12), match='Times-Roman'>
>>> print(standard14.search("/Times-BoldItalic"))
<_sre.SRE_Match object; span=(1, 17), match='Times-BoldItalic'>
>>> print(standard14.search("/Courier-Italic"))
<_sre.SRE_Match object; span=(1, 9), match='Courier-'>
>>> print(standard14.search("/Helvetica-Bold"))
<_sre.SRE_Match object; span=(1, 15), match='Helvetica-Bold'>
>>> print(standard14.search("/Courier-Oblique"))
<_sre.SRE_Match object; span=(1, 16), match='Courier-Oblique'>(我知道Arial,?(Bold)?(Italic)?公司有“假阳性”的可能。)
但是,运行"in eclipse“(4.6.3 PyDev 5.8):
>>> import sys
>>> print(sys.version)
3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:01:18) [MSC v.1900 32 bit (Intel)]
>>> print(standard14.search("/Times-Roman"))
None
>>> print(standard14.search("/Courier-Oblique"))
<_sre.SRE_Match object; span=(1, 8), match='Courier'>
>>> print(standard14.search("/Helvetica-Bold"))
<_sre.SRE_Match object; span=(1, 10), match='Helvetica'>(“时代-罗马”特别有趣,我甚至试过“反斜杠”)
我没什么想法了。
发布于 2018-03-12 02:03:25
这里的问题是源代码中的原始standard14Names使用的是Unicode MINUS SIGN字符(U+2212),而不是ASCII连字符(U+002D)。修复方法是将源中的-字符替换为-。
您会注意到,这些字符在视觉上看起来几乎相同,因此几乎不可能进行调试。当一个在Eclipse中,另一个在终端窗口中时,问题就更大了,所以它们甚至可能不是相同的字体…。
而且,当复制到剪贴板时,Eclipse显然使用replace-type处理程序将Unicode文本转换为ASCII,这有点令人费解。或者这可能是在粘贴上完成的终端,甚至是X11、Windows或其他介于两者之间的东西?
无论如何,如果未来的搜索程序有类似的问题,下面是调试它的明智方法:只需在每个环境中转储字符串的代码点,如下所示:
' '.join(hex(ord(ch)) for name in standard14Names for ch in name)可以很容易地查看这两个代码,并发现其中一个是纯的ASCII (两个字节十六进制代码点),而另一个则有大量的0x2212值。
一旦发现了这一点,您就可以查找第一个不同之处,然后很快就会看到每个0x2212都与另一个版本中的0x2d排成一行,此时(假设您不了解Unicode表),您可以搜索U+2212并找出到底发生了什么。
实际上,我推荐了一个傻瓜第一步--它无论如何都起作用了,但对于OP来说,这是更多的努力。可以通过在这两种环境中执行re.compile("|".join(standard14Names), re.DEBUG)来转储regex对象的编译信息。这不返回字符串,它实际上将输出转储到终端,因此您必须回滚并将其全部复制到文本文件中,以便对其进行任何有用的操作。而且,它将是非常长的。但是无论如何,如果将这两个版本都放入文本文件并进行diff,您将看到每个diff都是LITERAL 8722和LITERAL 45,而这些是0x2212和0x2d的十进制值,因此我们得到了与前一个版本相同的信息。
https://stackoverflow.com/questions/49226885
复制相似问题