我需要检测字符串中的最后一位数字,因为它们是我的字符串的索引。它们可能是 2^64,所以不方便只检查字符串中的最后一个元素,然后尝试第二个...等。字符串可能类似于asdgaf1_hsg534
,即字符串中也可能是其他数字,但中间有某处并且它们与我想要获取的索引不相邻。
3 回答
这是一种使用方法re.sub
:
import re
input = ['asdgaf1_hsg534', 'asdfh23_hsjd12', 'dgshg_jhfsd86']
for s in input:
print re.sub('.*?([0-9]*)$',r'\1',s)
输出:
534
12
86
解释:
该函数采用 a regular expression
、 areplacement string
和string
您要在以下位置进行替换的 the:re.sub(regex,replace,string)
正则表达式'.*?([0-9]*)$'
匹配整个字符串并捕获字符串末尾之前的数字。括号用于捕获我们感兴趣的匹配部分, \1
指的是第一个捕获组和\2
第二个等。
.*? # Matches anything (non-greedy)
([0-9]*) # Upto a zero or more digits digit (captured)
$ # Followed by the end-of-string identifier
所以我们用我们感兴趣的捕获的数字替换整个字符串。在python中,我们需要为此使用原始字符串r'\1'
:如果字符串不以数字结尾,则返回空白字符串。
twosixfour = "get_the_numb3r_2_^_64__18446744073709551615"
print re.sub('.*?([0-9]*)$',r'\1',twosixfour)
>>> 18446744073709551615
一个简单的正则表达式可以检测字符串末尾的数字:
'\d+$'
$
匹配字符串的结尾。\d+
匹配一位或多位数字。默认情况下,该+
运算符是贪婪的,这意味着它匹配尽可能多的数字。所以这将匹配字符串末尾的所有数字。
如果要使用re.sub
并确保行尾至少有一个数字,则可以使用量词+
匹配 1 个或多个数字\d+
,以在没有数字或没有数字的情况下不删除整行仅在行尾。
^.*?(\d+)$
^
线的开始.*?
尽可能少地匹配除换行符以外的任何字符(非贪婪)(\d+)
捕获组 1,匹配 1+ 位$
行结束
或使用负面的后视
^.*(?<!\d)(\d+)$
^
线的开始.*
尽可能匹配除换行符以外的任何字符(?<!\d)(\d+)
直接向左侧断言没有数字,然后在第 1 组中捕获 1+ 个数字$
行结束
使用re.match时,您可以省略^
锚点,也可以使用\A
and\Z
来声明字符串的开头和结尾。
import re
strings = ['asdgaf1_hsg534', 'asdfh23_hsjd12', 'dgshg_jhfsd86', 'test']
for s in strings:
print (re.sub(r".*?(\d+)$", r'\1',s))
输出
534
12
86
test
如果在匹配此注释中的数字之前应该存在非数字,则可以使用带有单个捕获组的否定字符类。
^.*[^\d\r\n](\d+)
^
线的开始.*
尽可能匹配除换行符以外的任何字符[^\d\r\n]
否定字符类,匹配除数字或换行符以外的任何字符(\d+)
捕获组 1,匹配 1+ 位
获取字符串中的最后一位数字(不一定在字符串的末尾)
^.*?(\d+)[^\r\n\d]*$
^
线的开始.*?
尽可能少地匹配除换行符以外的任何字符(非贪婪)(\d+)
捕获组 1,匹配 1+ 位[^\r\n\d]*
否定字符类,匹配除换行符或数字以外的任何字符 0+ 次$
行结束