2

我有这个正则表达式用于在 Python 代码中获取字符串:

x1 = re.compile('''((?P<unicode>u?)(?P<c1>'|")(?P<data>.+?)(?P<c2>'|"))''')

我想提取这个正则表达式的anddata部分来制作一个替换字符串(如果) ,比如:c1c2c1 == c2

repl = "u<c1><data><c2>"

我怎样才能做到这一点??
这可能在一行中还是通过使用re.sub

更新
我的新代码:

x1 = re.compile('''(?P<unicode>u?)(?P<c>'|")(?P<data>.*?)(?P=c)''')
def repl(match):
    if '#' in match.string:
        ### Confused
    return "u%(c)s%(data)s%(c)s" % m.groupdict()

fcode = '\n'.join([re.sub(x1,repl,i) for i in scode.splitlines()])

在这里,我在确定如何不更改评论中的字符串时遇到问题,我该怎么做才能忽略评论?

4

2 回答 2

1

假设你有一个模式:

pattern = r'''(?P<unicode>u?)(?P<c>'|")(?P<data>.*?)(?P=c)''' # did a little tweak

匹配一个字符串:

m = re.search(pattern, "print('hello')")

你有什么:

>>> m.groups()
('', '"', 'hello')
>>> m.groupdict()
{'c': '"', 'unicode': '', 'data': 'hello'}

现在你可以用这些做任何你想做的事情:

>>> 'u{c}{data}{c}'.format_map(m.groupdict())
'u"hello"'

也许您正在使用 Python 2.x:

>>> 'u{c}{data}{c}'.format(**m.groupdict())
'u"hello"'

甚至你喜欢老%

>>> "u%(c)s%(data)s%(c)s" % m.groupdict()
'u"hello"'

编辑

正则表达式解决方案无法正确处理某些情况。

所以我使用了一个2to3hack(实际上是3to2,仍然无法解决所有问题):

cd /usr/lib/python3.3/lib2to3/fixes/
cp fix_unicode.py fix_unicode33.py

编辑fix_unicode33.py

-_literal_re = re.compile(r"[uU][rR]?[\'\"]")
+_literal_re = re.compile(r"[rR]?[\'\"]")

-class FixUnicode(fixer_base.BaseFix):
+class FixUnicode33(fixer_base.BaseFix):

-                new.value = new.value[1:]
+                new.value = 'u' + new.value

现在2to3 --list | grep unicode33应该输出unicode33

然后就可以运行了2to3 -f unicode33 py3files.py

记得删除fix_unicode33.py

注意:在 Python3 中ur"string"抛出SyntaxError. 这里的逻辑很简单,修改它以达到你的目标。

于 2013-03-17T04:17:57.937 回答
0

我最终得到的长代码。

x1 = re.compile('''(?P<unicode>u?)(?P<c>'|")(?P<data>.*?)(?P=c)''')

def in_string(text,index):
    curr,in_l,in_str,level = '',0,False,[]

    for c in text[:index+1]:
        if c == '"' or c == "'":
            if in_str and curr == c:
                instr = False
                curr = ''
                in_l -= 1
            else:
                instr = True
                curr = c
                in_l += 1
        level.append(in_l)
    return bool(level[index])

def repl(m):
    return "u%(c)s%(data)s%(c)s" % m.groupdict()

def handle_hashes(i):
    if i.count('#') == 1:
        n = i.find('#')
    else:
        n = get_hash_out_of_string(i)
    return re.sub(x1,repl,i[:n]) + i[n:]

def get_hash_out_of_string(i):
    n = i.find('#')
    curr = i[:]
    last = (len(i)-1)-''.join(list(reversed(i))).find('#')
    while in_string(curr,n) and n < last:
        curr = curr[:n]+' '+curr[n+1:]
        n = curr.find('#')
    return n
于 2013-03-18T04:46:49.693 回答