我有以下标识符:
id1 = '883316040119_FRIENDS_HD'
id2 = 'ZWEX01DE9463DB_DMD'
id3 = '35358fr1'
id4 = 'as3d99j_br001'
我需要一个正则表达式来获取以下输出:
id1 = '883316040119'
id2 = 'ZWEX01DE9463DB'
id3 = '35358'
id4 = 'as3d99j'
这是我到目前为止所拥有的 -
re.sub(r'_?([a-zA-Z]{2,4}?\d?(00\d)?)$','',vendor_id)
它不能完美地工作,这是它给我的东西:
BAD - 883316040119_FRIENDS
GOOD - ZWEX01DE9463DB
GOOD - 35358
GOOD - as3d99j
什么是正确的正则表达式来获得所有这些?对于第一个,我基本上想要删除结尾,如果它只是下划线和字母,那么1928h9829_bundle_hd --> 1928h9829
。
请注意,我这里有数十万个标识符,并且我需要使用正则表达式。我不是在寻找python split()
方法,因为它不起作用。
答案 0 :(得分:2)
您提出输入的方式,我建议使用这个简单的正则表达式:
^(?:[^_]+(?=_)|\d+)
如果您想要向规范添加详细信息,可以进行调整。
为了向您展示正则表达式演示,仅仅因为网站regex101的工作方式,我们必须添加\n
(它假设我们正在处理整个文件,而不是一次一个输入):<强> DEMO 强>
<强>解释强>
^
锚点断言我们位于字符串的开头(?: ... )
匹配[^_]+(?=_)
非下划线字符(后跟下划线,未匹配)|
或\d+
位数答案 1 :(得分:1)
这适用于示例:
for id in ids :
print (id)
883316040119_FRIENDS_HD
ZWEX01DE9463DB_DMD
35358fr1
as3d99j_br001
for id in ids :
hit = re.sub( "(_[A-Za-z_]*|_?[A-Za-z]{2,4}?\d?(00\d)?)$", "", id)
print (hit)
883316040119
ZWEX01DE9463DB
35358
as3d99j
当尾部包含字母和下划线时,图案很方便,并剥去任意数量的下划线和数字;如果尾部不包含下划线,或者在下划线后面包含数字,那么它需要问题中的模式:0/2/3/4个字母然后是可选数字,然后是可选的零零数字。
答案 2 :(得分:0)
您正在检查下划线只有一个时间,因为?
表示{0,1}
。
r'(_[a-zA-Z]{2,}\d?(00[0-9])?|[a-z]{2,}\d)+$'
答案 3 :(得分:0)
以下内容从您的输入中重现您想要的结果。
我会在这个正则表达式中使用replace方法:
_[^']+|(?!.*_)('[0-9]+)[^']+
并返回捕获组1
也许:
result = re.sub("_[^']+|(?!.*_)('[0-9]+)[^']+", r"\1", subject)
正则表达式首先寻找下划线。如果找到一个,它将匹配所有内容但不包括下一个单引号;这将被删除。
如果不匹配,替代方案将查找没有下划线的字符串;匹配并返回捕获组1的数字序列;然后将数字后面的所有内容替换为但不包括单引号。
答案 4 :(得分:0)
这不是减法方法。只需捕获匹配的字符串。
正则表达式为^[0-9]+)|(^[a-zA-Z0-9]+(?=_)
。(即(^\d+)|(^[\d\w]+(?=_))
)
import re
id1 = '883316040119_FRIENDS_HD'
id2 = 'ZWEX01DE9463DB_DMD'
id3 = '35358fr1'
id4 = 'as3d99j_br001'
ids = [id1, id2, id3, id4]
for i in ids:
try:
print re.match(r"(^[0-9]+)|(^[a-zA-Z0-9]+(?=_))", i).group()
except:
print "not matched"
输出:
883316040119
ZWEX01DE9463DB
35358
as3d99j