在python中切分字符串

2024-03-28 08:25:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我想用这样的结构构建正则表达式:

    [['mirna', 'or', 'microrna'], 'or', 'lala']

…我想递归地提取'or'的左边部分来构建我的正则表达式。 如您所见,有时它是另一个嵌入列表,有时它是一个字符串。你知道吗

我的正则表达式应该是这样的:

((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

我猜当我提取单个单词时,切片会把它转换成一个列表。 但是我怎样才能把最后一个词和一张单子区分开来呢? 我已经花了好几个小时找不到解决办法,我完全迷路了。你知道吗


Tags: orselfrightifisrequestnotleft
3条回答

我认为您的代码有很多问题(例如不需要外包装列表和将字符串拆分为列表),所以我在这里重写了它。您只需要在列表上递归,为“or”追加“|”,并为所有其他情况追加字符串。你知道吗

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]) + ')'

编辑:正如弗朗西斯科指出的(不确定他为什么删除了他的评论),用result += re.escape(x)替换result += 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)

相关问题 更多 >