[英]slice a string in python list
我想從這樣的結構構建一個正則表達式:
[['mirna', 'or', 'microrna'], 'or', 'lala']
...並且我想遞歸地提取“或”的左側部分以構建我的正則表達式。 如您所見,有時是另一個嵌入列表,有時是字符串。
我的正則表達式應如下所示:
((mirna|microrna)|lala)
這就是我的算法(遞歸,因為我永遠不知道我的結構有多深):
def _buildRegex(self, request):
if not isinstance(request, str):
print(request)
print('request not a str')
request = request[0]
for i, e in enumerate(request):
self._print(i)
self._print(e)
if e == 'or':
self._print('OR found')
if isinstance(request, str):
print('left is str')
left = request
else:
print('left is list')
left = request[0:i]
if isinstance(request, str):
print('right is str')
right = request
else:
print('right is list')
right = request[i+1:len(request)-1]
print('(')
if isinstance(left, list):
self._buildRegex(left)
else:
print(left)
print('|')
if isinstance(right, list):
self._buildRegex(right)
else:
print(left)
print(')')
這就是我得到的:
[[['mirna', 'or', 'microrna'], 'or', 'lala']]
request not a str
0
['mirna', 'or', 'microrna']
1
or
OR found
left is list
right is list
(
[['mirna', 'or', 'microrna']]
request not a str
0
mirna
1
or
OR found
left is list
right is list
(
['mirna']
request not a str
0
m
1
i
2
r
3
n
4
a
|
[]
request not a str
我猜想當我提取單個單詞時,切片會將其轉換為列表。 但是,如何區分列表中的最后一個詞呢? 我已經花了很多時間,卻找不到解決方案,我完全迷失了。
我認為您的代碼有很多問題(例如不需要外部包裝列表並將字符串拆分為列表),因此我在此處進行了重寫。 您只需要在列表上遞歸,附加'|' 代表“或”,並為所有其他情況附加字符串。
def buildRegex(request):
result = '('
for x in request:
if not isinstance(x, str):
result += buildRegex(x)
elif x == 'or':
result += '|'
else:
result += x
result += ')'
return result
inp = [['mirna', 'or', 'microrna'], 'or', 'lala']
print(buildRegex(inp))
inp = [['mirna', 'or', ['hello', 'or', 'microrna']], 'or', ['lala', 'or','lele']]
print(buildRegex(inp))
輸出:
((mirna|microrna)|lala)
((mirna|(hello|microrna))|(lala|lele))
編輯:這是一個帶有列表理解的版本,只是為了好玩。 我認為它不太可讀:
def buildRegex(request):
return '(' + ''.join([buildRegex(x) if isinstance(x, list) else '|' if x == 'or' else x for x in request]) + ')'
編輯:正如Francisco指出的(不確定他為什么刪除他的評論),將result += x
替換為result += re.escape(x)
可能是一個好主意,以便您可以使用'|'之類的字符 直接在您的字符串中。
這似乎為我工作
def list_to_regex(input, final=''):
if isinstance(input, list):
if all([isinstance(x,str) for x in input]):
# pure list found
y = ''.join(['|' if z == 'or' else z for z in input])
to_add = '(' + y + ')'
return to_add
else:
# mixed list
for el in input:
final += list_to_regex(el, final)
return '(' + final + ')'
else:
# just a string
if input == 'or':
return '|'
else:
return input
樣品用法:
l = [['mirna', 'or', ['hello', 'or', 'microrna']], 'or', ['lala', 'or','lele']]
# ((mirna|(hello|microrna))|(lala|lele))
這有點俗氣,我已經想到了附帶情況。 如果考慮一下,嵌套列表已經基本上是所需的格式,那么只需將其設為字符串並進行一些替換即可。
碼:
data = [['mirna', 'or', 'microrna'], 'or', 'lala']
my_regex = str(data).replace(' ','').replace('[','(').replace(']',')').replace(",'or',",'|').replace("'",'').replace('"','')
print('my_regex='+my_regex)
它也可以與@Millie的第二個測試用例一起使用(感謝這樣做!)
輸出:
my_regex=((mirna|microrna)|lala)
這是適用於我的代碼,帶有錯誤檢查功能:
def build_regex(req):
if (type(req) != list and type(req) != str):
print('Error: Incompatible types')
return -1
if type(req) == list and len(req) % 2 != 1:
print("Even length, missing an or somewhere")
return -1
if type(req) == str:
return req
if len(req) == 1:
return build_regex(req[0])
if type(req[0]) == list:
return '(' + build_regex(req[0]) + '|' + build_regex(req[2:]) + ')'
if type(req[0]) == str:
return '(' + req[0] + '|' + build_regex(req[2:]) + ')'
print("Error: Incompatible element types.")
print("Required str or list, found " + type(req[0]))
return -1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.