1

PDFファイルの仕様に従って名前オブジェクトを一致させる必要があります。ただし、特殊文字を指定するために、名前に 16 進数 (先頭に #) を含めることができます。これらの一致を対応する文字に変換したいと思います。一致文字列を再解析せずにそれを行う賢い方法はありますか?

import re

Name = re.compile(r'''
    (/                                        # Literal "/"
        (?:                                   #
            (?:\#[A-Fa-f0-9]{2})              # Hex numbers
            |                                 # 
            [^\x00-\x20 \x23 \x2f \x7e-\xff]  # Other
        )+                                    #
    )                                         #
    ''', re.VERBOSE)

#  some examples

names = """
    The following are examples of valid literal names:

    Raw string                       Translation

    1.  /Adobe#20Green            -> "Adobe Green"
    2.  /PANTONE#205757#20CV      -> "PANTONE 5757 CV"
    3.  /paired#28#29parentheses  -> "paired( )parentheses"
    4.  /The_Key_of_F#23_Minor    -> "The_Key_of_F#_Minor"
    5.  /A#42                     -> "AB"
    6.  /Name1
    7.  /ASomewhatLongerName
    8.  /A;Name_With-Various***Characters?
    9.  /1.2
    10. /$$
    11. /@pattern
    12. /.notdef
    """
4

2 に答える 2

1

finditer()ラッパージェネレーターで使用します:

import re
from functools import partial

def _hexrepl(match):
    return chr(int(match.group(1), 16))
unescape = partial(re.compile(r'#([0-9A-F]{2})').sub, _hexrepl)

def pdfnames(inputtext):
    for match in Name.finditer(inputtext):
        yield unescape(match.group(0))

デモ:

>>> for name in pdfnames(names):
...     print name
... 
/Adobe Green
/PANTONE 5757 CV
/paired()parentheses
/The_Key_of_F#_Minor
/AB
/Name1
/ASomewhatLongerName
/A;Name_With-Various***Characters?
/1.2
/$$
/@pattern
/.notdef

が知る限り、これほど巧妙な方法はありません。それ以外の場合、reエンジンは置換とマッチングを組み合わせることができません。

于 2013-06-17T10:19:39.007 に答える
1

をご覧くださいre.sub

これを関数で使用して、16 進数の '#[0-9A-F]{2}' 番号を照合し、関数を使用してこれらを変換できます。

例えば

def hexrepl(m):
    return chr(int(m.group(0)[1:3],16))

re.sub(r'#[0-9A-F]{2}', hexrepl, '/Adobe#20Green')

「/Adobe Green」を返します

于 2013-06-17T10:13:23.753 に答える