使用 Python 正则表达式在模式内剪切
Cut within a pattern using Python regex
Objective: 我正在尝试在 Python RegEx 中进行切割,其中拆分并不完全符合我的要求。我需要在模式内剪切,但在字符之间剪切。
我要找的是:
我需要在字符串中识别下面的模式,并在管道的位置拆分字符串。管道实际上并不在字符串中,它只是显示我要拆分的位置。
模式:CDE|FG
字符串:ABCDEFGHIJKLMNOCDEFGZYPE
结果:['ABCDE', 'FGHIJKLMNOCDE', 'FGZYPE']
我试过的:
我似乎使用带括号的拆分很接近,但它并没有像我需要的那样将搜索模式附加到结果。
re.split('CDE()FG', 'ABCDEFGHIJKLMNOCDEFGZYPE')
给予,
['AB', 'HIJKLMNO', 'ZYPE']
当我真正需要的时候,
['ABCDE', 'FGHIJKLMNOCDE', 'FGZYPE']
动机:
正在练习 RegEx,想看看我是否可以使用 RegEx 制作一个脚本来预测使用特定蛋白酶消化蛋白质的片段。
你可以用re.split()
和积极的"look arounds"解决它:
>>> re.split(r"(?<=CDE)(\w+)(?=FG)", s)
['ABCDE', 'FGHIJKLMNOCDE', 'FGZYPE']
请注意,如果其中一个剪切序列是空字符串,您将在结果列表中得到一个空字符串。你可以处理 "manually",示例(我承认,它不是那么漂亮):
import re
s = "ABCDEFGHIJKLMNOCDEFGZYPE"
cut_sequences = [
["CDE", "FG"],
["FGHI", ""],
["", "FGHI"]
]
for left, right in cut_sequences:
items = re.split(r"(?<={left})(\w+)(?={right})".format(left=left, right=right), s)
if not left:
items = items[1:]
if not right:
items = items[:-1]
print(items)
打印:
['ABCDE', 'FGHIJKLMNOCDE', 'FGZYPE']
['ABCDEFGHI', 'JKLMNOCDEFGZYPE']
['ABCDE', 'FGHIJKLMNOCDEFGZYPE']
一种非正则表达式的方式是 replace the pattern with the piped value and then split。
>>> pattern = 'CDE|FG'
>>> s = 'ABCDEFGHIJKLMNOCDEFGZYPE'
>>> s.replace('CDEFG',pattern).split('|')
['ABCDE', 'FGHIJKLMNOCDE', 'FGZYPE']
一个更安全的非正则表达式解决方案可能是这样的:
import re
def split(string, pattern):
"""Split the given string in the place indicated by a pipe (|) in the pattern"""
safe_splitter = "#@#@SPLIT_HERE@#@#"
safe_pattern = pattern.replace("|", safe_splitter)
string = string.replace(pattern.replace("|", ""), safe_pattern)
return string.split(safe_splitter)
s = "ABCDEFGHIJKLMNOCDEFGZYPE"
print(split(s, "CDE|FG"))
print(split(s, "|FG"))
print(split(s, "FGH|"))
要在使用 re.split
或其中的一部分拆分时保持拆分模式,请将它们括在括号中。
>>> data
'ABCDEFGHIJKLMNOCDEFGZYPE'
>>> pieces = re.split(r"(CDE)(FG)", data)
>>> pieces
['AB', 'CDE', 'FG', 'HIJKLMNO', 'CDE', 'FG', 'ZYPE']
很简单。所有零件都在那里,但正如您所见,它们已被分开。所以我们需要重新组装它们。那是比较棘手的部分。仔细观察,您会发现您需要将前两块、后两块和其余三块拼接起来。我通过填充列表来简化代码,但如果性能有问题,您可以使用原始列表(和一些额外的代码)来完成。
>>> pieces = [""] + pieces
>>> [ "".join(pieces[i:i+3]) for i in range(0,len(pieces), 3) ]
['ABCDE', 'FGHIJKLMNOCDE', 'FGZYPE']
re.split()
保证每个捕获(带括号的)组都有一块,加上介于两者之间的一块。对于需要自己分组的更复杂的正则表达式,使用非捕获组来保持返回数据的格式相同。 (否则您需要调整重组步骤。)
PS。我也喜欢 Bhargav Rao 关于在字符串中插入分隔符的建议。如果性能不是问题,我想这是一个品味问题。
编辑:这是一种(不太透明的)方法,无需向列表中添加空字符串:
pieces = re.split(r"(CDE)(FG)", data)
result = [ "".join(pieces[max(i-3,0):i]) for i in range(2,len(pieces)+2, 3) ]
Objective: 我正在尝试在 Python RegEx 中进行切割,其中拆分并不完全符合我的要求。我需要在模式内剪切,但在字符之间剪切。
我要找的是:
我需要在字符串中识别下面的模式,并在管道的位置拆分字符串。管道实际上并不在字符串中,它只是显示我要拆分的位置。
模式:CDE|FG
字符串:ABCDEFGHIJKLMNOCDEFGZYPE
结果:['ABCDE', 'FGHIJKLMNOCDE', 'FGZYPE']
我试过的:
我似乎使用带括号的拆分很接近,但它并没有像我需要的那样将搜索模式附加到结果。
re.split('CDE()FG', 'ABCDEFGHIJKLMNOCDEFGZYPE')
给予,
['AB', 'HIJKLMNO', 'ZYPE']
当我真正需要的时候,
['ABCDE', 'FGHIJKLMNOCDE', 'FGZYPE']
动机:
正在练习 RegEx,想看看我是否可以使用 RegEx 制作一个脚本来预测使用特定蛋白酶消化蛋白质的片段。
你可以用re.split()
和积极的"look arounds"解决它:
>>> re.split(r"(?<=CDE)(\w+)(?=FG)", s)
['ABCDE', 'FGHIJKLMNOCDE', 'FGZYPE']
请注意,如果其中一个剪切序列是空字符串,您将在结果列表中得到一个空字符串。你可以处理 "manually",示例(我承认,它不是那么漂亮):
import re
s = "ABCDEFGHIJKLMNOCDEFGZYPE"
cut_sequences = [
["CDE", "FG"],
["FGHI", ""],
["", "FGHI"]
]
for left, right in cut_sequences:
items = re.split(r"(?<={left})(\w+)(?={right})".format(left=left, right=right), s)
if not left:
items = items[1:]
if not right:
items = items[:-1]
print(items)
打印:
['ABCDE', 'FGHIJKLMNOCDE', 'FGZYPE']
['ABCDEFGHI', 'JKLMNOCDEFGZYPE']
['ABCDE', 'FGHIJKLMNOCDEFGZYPE']
一种非正则表达式的方式是 replace the pattern with the piped value and then split。
>>> pattern = 'CDE|FG'
>>> s = 'ABCDEFGHIJKLMNOCDEFGZYPE'
>>> s.replace('CDEFG',pattern).split('|')
['ABCDE', 'FGHIJKLMNOCDE', 'FGZYPE']
一个更安全的非正则表达式解决方案可能是这样的:
import re
def split(string, pattern):
"""Split the given string in the place indicated by a pipe (|) in the pattern"""
safe_splitter = "#@#@SPLIT_HERE@#@#"
safe_pattern = pattern.replace("|", safe_splitter)
string = string.replace(pattern.replace("|", ""), safe_pattern)
return string.split(safe_splitter)
s = "ABCDEFGHIJKLMNOCDEFGZYPE"
print(split(s, "CDE|FG"))
print(split(s, "|FG"))
print(split(s, "FGH|"))
要在使用 re.split
或其中的一部分拆分时保持拆分模式,请将它们括在括号中。
>>> data
'ABCDEFGHIJKLMNOCDEFGZYPE'
>>> pieces = re.split(r"(CDE)(FG)", data)
>>> pieces
['AB', 'CDE', 'FG', 'HIJKLMNO', 'CDE', 'FG', 'ZYPE']
很简单。所有零件都在那里,但正如您所见,它们已被分开。所以我们需要重新组装它们。那是比较棘手的部分。仔细观察,您会发现您需要将前两块、后两块和其余三块拼接起来。我通过填充列表来简化代码,但如果性能有问题,您可以使用原始列表(和一些额外的代码)来完成。
>>> pieces = [""] + pieces
>>> [ "".join(pieces[i:i+3]) for i in range(0,len(pieces), 3) ]
['ABCDE', 'FGHIJKLMNOCDE', 'FGZYPE']
re.split()
保证每个捕获(带括号的)组都有一块,加上介于两者之间的一块。对于需要自己分组的更复杂的正则表达式,使用非捕获组来保持返回数据的格式相同。 (否则您需要调整重组步骤。)
PS。我也喜欢 Bhargav Rao 关于在字符串中插入分隔符的建议。如果性能不是问题,我想这是一个品味问题。
编辑:这是一种(不太透明的)方法,无需向列表中添加空字符串:
pieces = re.split(r"(CDE)(FG)", data)
result = [ "".join(pieces[max(i-3,0):i]) for i in range(2,len(pieces)+2, 3) ]