匹配Python整数文本的正则表达式

匹配Python整数文本的正则表达式,python,regex,Python,Regex,什么是正则表达式,它将匹配字符串中任何有效的Python整数文本?它应该支持所有额外的东西,比如o和l,但不匹配浮点或带有数字的变量。我使用的是Python的re,所以它支持的任何语法都是可以的 编辑:这是我的动机(显然这很重要)。我正在努力修复。我想做的是为IPython创建一个钩子,它自动将int/int(比如1/2)转换为Rational(int,int),(比如Rational(1,2)。原因是,否则就不可能将1/2注册为一个有理数,因为它是Python类型\uuu div\uuuuPy

什么是正则表达式,它将匹配字符串中任何有效的Python整数文本?它应该支持所有额外的东西,比如
o
l
,但不匹配浮点或带有数字的变量。我使用的是Python的
re
,所以它支持的任何语法都是可以的

编辑:这是我的动机(显然这很重要)。我正在努力修复。我想做的是为IPython创建一个钩子,它自动将int/int(比如
1/2
)转换为
Rational(int,int)
,(比如
Rational(1,2)
。原因是,否则就不可能将
1/2
注册为一个有理数,因为它是Python类型
\uuu div\uuuu
Python类型。在Symphy中,这可能非常烦人,因为像
x**(1/2)
这样的东西会创建
x**0
(或者
x**0.5
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu)除法或Python 3),当您想要

我的解决方案是向IPython添加一个钩子,该钩子会自动将输入中的所有整数文本包装为整数(Symphy的自定义整数类,该类在除法时给出
Rational
)。这将允许我在
isympy
中添加一个选项,让Symphy在这方面更像传统的计算机代数系统,适合需要它的人。我希望这可以解释为什么我需要它来匹配任意Python表达式中的任何和所有文本,这就是为什么它不需要将浮点文本和变量与数字匹配在他们的名字里

另外,由于每个人都对我尝试的内容非常感兴趣,这里是:在我放弃之前不多(正则表达式很难)。我玩了
(?!\)
,使它不捕捉浮点文本的第一部分,但这似乎不起作用(我很好奇是否有人能告诉我为什么,例如
re.sub(r)(\d*(?!\)、r“s”(\1\)、“12.1”)


编辑2:由于我计划将其与
re.sub
结合使用,您最好将整个内容用括号括起来,以便我可以使用
\1
:)

中描述了语法。这里有一种方法将其表示为正则表达式:

(0|[1-9][0-9]*|0[oO]?[0-7]+|0[xX][0-9a-fA-F]+|0[bB][01]+)[lL]?
免责声明:这不支持负整数,因为在Python中,类似于
-31
中的
-
实际上不是整数文本的一部分,而是一个单独的运算符。

是(在3.x中,在2.x中略有不同):

比如说:

[1-9]\d*|0|0[oO][0-7]+|0[xX][\da-fA-F]+|0[bB][01]+

基于说你想支持“l”,我猜你实际上想要:

哪些是可以写的

(?:[1-9]\d+|0|0[oO]?[0-7]+|0[xX][\da-fA-F]+|0[bB][01]+)[lL]?

这非常接近:

re.match('^(0[x|o|b])?\d+[L|l]?$', '0o123l')

这样的东西够了吗

r = r"""
(?<![\w.])               #Start of string or non-alpha non-decimal point
    0[X][0-9A-F]+L?|     #Hexadecimal
    0[O][0-7]+L?|        #Octal
    0[B][01]+L?|         #Binary
    [1-9]\d*L?           #Decimal/Long Decimal, will not match 0____
(?![\w.])                #End of string or non-alpha non-decimal point
"""
r=r”“”

(?如果您真的想匹配两种“方言”,您会遇到一些歧义,例如八进制(Python 3中需要
o

r = r"""(?xi) # Verbose, case-insensitive regex
(?<!\.)       # Assert no dot before the number
\b            # Start of number
(?:           # Match one of the following:
 0x[0-9a-f]+| # Hexadecimal number
 0o?[0-7]+|   # Octal number
 0b[01]+|     # Binary number
 0+|          # Zero
 [1-9]\d*     # Other decimal number
)             # End of alternation
L?            # Optional Long integer
\b            # End of number
(?!\.)        # Assert no dot after the number"""
r=r”“(?xi)#详细,不区分大小写的正则表达式

(?我不相信使用re是一种可行的方法。Python有
标记化
ast
符号
解析器
模块,可用于解析/处理/操作/重写Python代码

>>> s = "33.2 + 6 * 0xFF - 0744"
>>> from StringIO import StringIO
>>> import tokenize
>>> t = list(tokenize.generate_tokens(StringIO(s).readline))
>>> t
[(2, '33.2', (1, 0), (1, 4), '33.2 + 6 * 0xFF - 0744'), (51, '+', (1, 5), (1, 6), '33.2 + 6 * 0xFF - 0744'), (2, '6', (1, 7), (1, 8), '33.2 + 6 * 0xFF - 0744'), (51, '*', (1, 9), (1, 10), '33.2 + 6 * 0xFF - 0744'), (2, '0xFF', (1, 11), (1, 15), '33.2 + 6 * 0xFF - 0744'), (51, '-', (1, 16), (1, 17), '33.2 + 6 * 0xFF - 0744'), (2, '0744', (1, 18), (1, 22), '33.2 + 6 * 0xFF - 0744'), (0, '', (2, 0), (2, 0), '')]
>>> nums = [eval(i[1]) for i in t if i[0] == tokenize.NUMBER]
>>> nums
[33.2, 6, 255, 484]
>>> print map(type, nums)
[<type 'float'>, <type 'int'>, <type 'int'>, <type 'int'>]
>>s=“33.2+6*0xFF-0744”
>>>从StringIO导入StringIO
>>>导入标记化
>>>t=list(tokenize.generate_令牌(StringIO.readline))
>>>t
“33.2+6+6*0-0744’,,(51,”51,,,,,(1、5)、(1、1、6)、(1、1、6),“33.2+6+6+6+6+6+6*0*0-0704-0704-0744’,,,(2,,,,(2,,,,,,(2,,,,,,(2,,,,,,,(2,,,,,,,,(2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,(51,,,,(51,,,(51,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,(51.3.3.3.2,”33.2.2+3.2+3.2+2,(1,22),"33.2+6*0xFF-0744","0","2,0","2,0",
>>>如果i[0]==tokenize.NUMBER,则t中i的nums=[eval(i[1])
>>>努姆斯
[33.2, 6, 255, 484]
>>>打印地图(类型,nums)
[, , ]

这里有一个例子,将浮动重新写入为
decimal。decimal

缺少格式,例如
0755
作为十六进制文字;还需要
[lL]
现在就结束了。如果
-
是分开的就可以了。我现在所做的一切都会很好。嗯,
-
的有趣之处。现在我想起来,它应该是一个单独的操作符。@Dougal:换句话说,我错过了
的两个实例。不知道这是怎么发生的。Thanks指出了这一点;现在修复了。我实际上想要两者。谢谢!这仍然匹配浮点文本的第一部分和包含数字的变量的数字部分。我还没有写它,但看起来Python文档中的十进制示例几乎正是我想要的。呃,在看了一些答案之后,我的将提供消除很多误报,完全跳过十六进制文字。哇,即使在我提到限制之后,对一个不完整的答案投反对票?数字-缺少一个向上投票应该足够了。根据我的经验,你必须删除你的错误答案,否则他们将被否决而被遗忘(不过老实说,如果我是你,我就不会太担心自己的声誉了)@阿斯穆勒:是的,你是对的——我想,我对声誉的担心没有教育那么多。你需要知道的一切都在我做的研究中。我在谷歌上搜索了它,甚至自己也尝试过。结果一无所获。我没有把它包括在问题中,因为我觉得它与我无关。考虑到所有答案都不正确o到目前为止,我想说这不是一个小问题。@asmuler通常最好发布错误/不完整的解决方案(在问题中)仅仅因为这个原因,没有什么比什么都好。另外,在回答问题的其余部分时提到你为什么要做某事也很方便,因为可能还有其他你没有想到的解决方案比你要求的更好。我同意@JoshSmeaton。如果我有点粗鲁,我很抱歉。如果你编辑你的任务
r = r"""(?xi) # Verbose, case-insensitive regex
(?<!\.)       # Assert no dot before the number
\b            # Start of number
(?:           # Match one of the following:
 0x[0-9a-f]+| # Hexadecimal number
 0o?[0-7]+|   # Octal number
 0b[01]+|     # Binary number
 0+|          # Zero
 [1-9]\d*     # Other decimal number
)             # End of alternation
L?            # Optional Long integer
\b            # End of number
(?!\.)        # Assert no dot after the number"""
>>> s = "33.2 + 6 * 0xFF - 0744"
>>> from StringIO import StringIO
>>> import tokenize
>>> t = list(tokenize.generate_tokens(StringIO(s).readline))
>>> t
[(2, '33.2', (1, 0), (1, 4), '33.2 + 6 * 0xFF - 0744'), (51, '+', (1, 5), (1, 6), '33.2 + 6 * 0xFF - 0744'), (2, '6', (1, 7), (1, 8), '33.2 + 6 * 0xFF - 0744'), (51, '*', (1, 9), (1, 10), '33.2 + 6 * 0xFF - 0744'), (2, '0xFF', (1, 11), (1, 15), '33.2 + 6 * 0xFF - 0744'), (51, '-', (1, 16), (1, 17), '33.2 + 6 * 0xFF - 0744'), (2, '0744', (1, 18), (1, 22), '33.2 + 6 * 0xFF - 0744'), (0, '', (2, 0), (2, 0), '')]
>>> nums = [eval(i[1]) for i in t if i[0] == tokenize.NUMBER]
>>> nums
[33.2, 6, 255, 484]
>>> print map(type, nums)
[<type 'float'>, <type 'int'>, <type 'int'>, <type 'int'>]