我使用的是gedit regex插件(Python风格的regex)。我想在一个组的反向引用上做一些算术运算。
例如:
PART 1 DATA MODELS Chapter
2 Entity-Relationship Model 27
我想把它改成
PART 1 DATA MODELS Chapter 25
2 Entity-Relationship Model 27
我的正则表达式是^(PART.*)\n(.*\s(\d+))\n
,我想将其替换为类似\1 (\3-2)\n\2\n
的内容,其中\3-2
是反向引用\3
减去2。但是替换正则表达式是不正确的。我想知道怎么做?谢谢!
发布于 2011-07-30 07:51:59
您可以传递给re.sub
lambda函数,该函数接受每个非重叠模式匹配的re.MatchObject
对象,并返回替换字符串。例如:
import re
print re.sub("(\d+)\+(\d+)",
lambda m: str(int(m.group(1))+int(m.group(2))),
"If 2+2 is 4 then 1+2+3+4 is 10")
打印
如果4是4,则3+7是10
你可以很容易地将它应用于你的问题。
发布于 2011-07-26 14:27:07
下面的代码对作为示例给出的字符串执行您想要的操作。有一点是,它非常特定于这一个字符串的格式。它不能管理字符串中的任何可变性。它实际上仅限于这种类型的字符串格式。
import re
ss = '''PART 1 DATA MODELS Chapter
2 Entity-Relationship Model 27
The sun is shining
PART 1 DATA MODELS Chapter
13 Entity-Relationship Model 45
'''
regx = re.compile('^(PART.*)(\n(\d*).*\s(\d+)\n)',re.MULTILINE)
def repl(mat):
return ''.join((mat.group(1),' ',
str(int(mat.group(4))-int(mat.group(3))),
mat.group(2)))
for mat in regx.finditer(ss):
print mat.groups()
print
print regx.sub(repl,ss)
结果
('PART 1 DATA MODELS Chapter', '\n2 Entity-Relationship Model 27\n', '2', '27')
('PART 1 DATA MODELS Chapter', '\n13 Entity-Relationship Model 45\n', '13', '45')
PART 1 DATA MODELS Chapter 25
2 Entity-Relationship Model 27
The sun is shining
PART 1 DATA MODELS Chapter 32
13 Entity-Relationship Model 45
编辑的:我忘记了re.MULTILINE标志
发布于 2011-07-26 11:02:00
我不知道你可以在正则表达式中进行算术或其他计算。如果有一个正则表达式引擎支持这一点,那就太棒了!但我的理解是,如果不大幅降低正则表达式引擎的速度,这将是不现实的。
我认为您最好的选择是使用sub
正则表达式函数/方法:
re.sub(pattern,repl,string,count,re.sub)
返回通过替换repl替换字符串中最左侧不重叠的pattern实例而获得的字符串。如果没有找到模式,则原封不动地返回字符串。repl可以是一个字符串,也可以是一个函数;如果它是一个字符串,则会处理其中的任何反斜杠转义。也就是说,\n转换为单个换行符,\r转换为换行符,依此类推。诸如\j之类的未知转义将被保留。反向引用(如\6 )将替换为模式中组6匹配的子字符串。对于example:
re.sub(r'def\s+(a-zA-Z_*)\s*(\s*):',..。R‘静态PyObject*\npy_\1(空)\n{’,...‘'def myfunc():')’静态函数(PyObject*\npy_myfunc)\n{‘
如果repl是一个函数,则每次出现非重叠的模式时都会调用该函数。此函数接受单个匹配对象参数,并返回替换字符串。例如:
def dashrepl(matchobj):...如果matchobj.group(0)返回'-':==‘’...否则:>>> '-‘re.sub(’-‘{1,2} ',dashrepl,’pro-gram- files‘)’程序--gram文件‘>>> re.sub(r’\>>>\s‘,’&‘,’烘豆和垃圾邮件‘,flags=re.IGNORECASE)’烘豆和垃圾邮件‘
模式可以是字符串或RE对象。
可选参数count是要替换的模式出现的最大数量;count必须是非负整数。如果省略或为零,则将替换所有出现的项。仅当与前一个匹配不相邻时,才会替换模式的空匹配,因此sub('x*','-','abc')返回'-a-b-c-‘。
除了如上所述的字符转义和反向引用之外,\g还将使用由(?P...)定义的名为name的组所匹配的子字符串语法。\g使用相应的组号;因此,\g<2>等同于\2,但在\g<2>0等替换项中不会有歧义。\20将被解释为对组20的引用,而不是对组2的引用,后跟文字字符“0”。与RE.匹配的整个子字符串中的反向引用\g<0>替换
您可以将repl作为计算要替换回原始字符串的值的函数进行传递。
https://stackoverflow.com/questions/6824471
复制相似问题