空格和^Not Working-Python 3中的多个正则表达式替换
从我的搜索中,我看到这类问题已经被问了很多次,我理解了规范的解决方案。但是,没有一个解决我遇到的具体问题。我正在尝试编写一个函数,用Python 3.4中的正则表达式从字符串中去除无意义字符(染色体ID来自我正在处理的任何不同类型的生物信息学文件)。关于可能出现的奇怪字符的种类没有一般规则,所以我们的想法是以这样一种方式来编写,即可以快速添加新的特殊情况,我在下面的代码中包含了一些示例 遵循其他几个帖子的逻辑: 等等 我写了以下内容:空格和^Not Working-Python 3中的多个正则表达式替换,python,regex,python-3.x,dictionary,ordereddictionary,Python,Regex,Python 3.x,Dictionary,Ordereddictionary,从我的搜索中,我看到这类问题已经被问了很多次,我理解了规范的解决方案。但是,没有一个解决我遇到的具体问题。我正在尝试编写一个函数,用Python 3.4中的正则表达式从字符串中去除无意义字符(染色体ID来自我正在处理的任何不同类型的生物信息学文件)。关于可能出现的奇怪字符的种类没有一般规则,所以我们的想法是以这样一种方式来编写,即可以快速添加新的特殊情况,我在下面的代码中包含了一些示例 遵循其他几个帖子的逻辑: 等等 我写了以下内容: def fix_chromosome_id(chr
def fix_chromosome_id(chromosome):
replacements = OrderedDict([(r'lcl|', ''),
(r'gi|', ''),
(r'chromosome', ''),
(r'^chr', ''),
(r'_+', ''),
(r'\s+', ''),
(r'^\s', ''),
(r'\s$', ''),
(r'/', '_'),
(r'|$', ''),
(r'|', '_'),
(r'(', '_'),
(r')', '_'),
(r'_+', '_')]) # Ordered dictionary of regex and substitutions from list of tuples
# Compile as regex objects, substitute regex as specified in the ordered dictionary
pattern = re.compile('|'.join(re.escape(regex) for regex in replacements))
chromosome = pattern.sub(lambda match: replacements[match.group(0)], chromosome, re.IGNORECASE)
您可以看到,我已经从元组列表创建了一个有序字典,因为替换的顺序可能很重要,而标准字典不会考虑这一点。然后将这些键用作正则表达式并尝试替换为相应的值
我的问题:
if re.search(r'^0+$', chromosome):
chromosome = 0
这对于用一个零替换任意数量的零组成的字符串来说效果很好
那么,上述代码有什么问题?如果你能看一看的话。我可以为每个特定实例键入
re.sub()
,但肯定有更有效的方法来做到这一点。用于构建OrderedDict
的简单的2元组列表可能是更好的数据结构,因为模式和其替换之间没有真正的键/值关系。此外,您还有一个重复的密钥,并且在字典中只会出现一次!将其保留为列表将使用更少的内存来引导(但可能不是主要因素)
我看到的主要问题是,您正在以编程方式转义模式。因此,模式中的特殊字符没有其特殊含义。例如,re.escape()
将+
更改为\+
,这意味着它现在匹配的是一个文字加号,而不是“前面的一个或多个字符”。这并不能解释您的一些问题(例如,大小写不敏感不起作用),但在解决此问题之前,您将对所有问题感到非常困惑
您可能应该做的是在原始模式中转义需要转义的内容(例如,我假设模式中的
字符,例如li
是为了匹配文本
,因此应该编写\\\
),而不使用re.escape()
另外,由于您没有对替换做任何花哨的操作,因此可以在调用中使用替换文本的
re.sub()
,而不是编写一个执行相同操作的lambda
。根据kindall的建议,我稍微简化了一些事情。lambda有时很方便,但在这种情况下并不需要,它会降低可读性。订购字典是个好主意,但没有必要
解决方案:
def fix_chromosome_id(chromosome):
replacements = [('lcl\|', ''),
('gi\|', ''),
('chromosome', ''),
('^chr', ''),
('^_+', ''),
('\s+', ''),
('^\s', ''),
('\s$', ''),
('\/', '_'),
('\|$', ''),
('\|', '_'),
('\(', '_'),
('\)', '_'),
('_+', '')] # Regex and substitutions from list of tuples
# Compile as regex objects, substitute regex as specified in the ordered dictionary
for rep_tuple in replacements:
regex_pattern = re.compile(rep_tuple[0], re.IGNORECASE)
rep = rep_tuple[1]
chromosome = regex_pattern.sub(rep, chromosome)
我不知道为什么re.IGNORECASE以前不起作用,但现在一切都好了。有一次,一个小建议被证明是非常有价值的!我正在使它变得更复杂,可读性更低,因此比我需要的分类字典更少“pythonic”。我仍然不太清楚所有的问题到底是什么,但现在通过消除这些问题和程序性转义,这些问题已经得到了解决。非常感谢。