首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >正则表达式中的算术运算

正则表达式中的算术运算
EN

Stack Overflow用户
提问于 2011-07-26 10:06:07
回答 4查看 4.1K关注 0票数 12

我使用的是gedit regex插件(Python风格的regex)。我想在一个组的反向引用上做一些算术运算。

例如:

代码语言:javascript
运行
复制
PART 1 DATA MODELS Chapter  
2 Entity-Relationship Model 27

我想把它改成

代码语言:javascript
运行
复制
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。但是替换正则表达式是不正确的。我想知道怎么做?谢谢!

EN

回答 4

Stack Overflow用户

发布于 2011-07-30 07:51:59

您可以传递给re.sub lambda函数,该函数接受每个非重叠模式匹配的re.MatchObject对象,并返回替换字符串。例如:

代码语言:javascript
运行
复制
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

你可以很容易地将它应用于你的问题。

票数 13
EN

Stack Overflow用户

发布于 2011-07-26 14:27:07

下面的代码对作为示例给出的字符串执行您想要的操作。有一点是,它非常特定于这一个字符串的格式。它不能管理字符串中的任何可变性。它实际上仅限于这种类型的字符串格式。

代码语言:javascript
运行
复制
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)

结果

代码语言:javascript
运行
复制
('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标志

票数 5
EN

Stack Overflow用户

发布于 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作为计算要替换回原始字符串的值的函数进行传递。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6824471

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档