如何在python中多次解析字符串?

时间:2016-02-04 12:36:15

标签: python

我有一个自定义脚本我想从python中提取数据,但我能想到的唯一方法是取出标记的位然后保留未标记的位,如" go up" "下来"在这个例子中。

string_a = [start]go up[wait time=500]go down[p]
string_b = @onclick go up[wait time=500]go down active="False"

在尝试这样做的时候,我所做的只是提取标记的位,但我无法找到一种方法来保存未标记的数据!当我提取其他位时,它总是迷失! 这是我用来提取它们的功能。为了削减标记,我多次调用它,但我无法选择它们被提取的顺序!

class Parsers:

  @staticmethod
  def extract(line, filters='[]'):
    #@retval list
    substring=line[:]
    contents=[]
    for bracket in range(line.count(str(filters[0]))):
      startend =[]
      for f in filters:
        now= substring.find(f)
        startend.append(now)
      contents.append(substring[startend[0]+1:startend[1]])
      substring=substring[startend[1]+1:]
    return contents, substring

顺便说一句,我现在正在调用它的顺序是这样的。我想我应该把订单放回@是第一个,但我不想再打破它。

star_string, first = Parsers.extract(string_a, filters='* ')
bracket_string, substring = Parsers.extract(string_a, filters='[]')
at_string, final = Parsers.extract(substring, filters='@ ')

请原谅我的坏蟒蛇,我自己学会了这一切,我仍然在想这个。

2 个答案:

答案 0 :(得分:0)

你正在用上面的Python字符串方法做一些强大的malabarisms - 但是如果你想要的只是在括号内提取内容,并获得字符串的其余部分,那么正则表达式就会更容易(在Python中, “重新”模块)

import re
string_a = "[start]go up[wait time=500]go down[p]"
expr = r"\[.*?\]"
expr = re.compile(r"\[.*?\]")
contents = expr.findall(string_a)
substring = expr.sub("", string_a)

这只是告诉regexp引擎匹配文字[,以及任何字符(.*),直到以下]?用于匹配下一个],而不是最后一个) - findall调用将所有此类匹配作为字符串列表获取,sub调用替换空字符串的所有匹配。

对于正则表达式来说,它们比他们自己的子编程语言更少。查看有关它们的文档:https://docs.python.org/2/library/re.html

但是,做一些更简单的方法就是逐个字符地检查,并且有一些变量来“知道”你在字符串中的位置(例如,如果在标签内部),就像我们一样如果我们一次只能看一个角色,就会想到这个问题。我将编写思考Python 3.x的代码 - 如果你仍在使用Python 2.x,请在尝试这样的事情之前将你的字符串转换为unicode对象:

def extract(line, filters='[]'):
    substring = ""
    contents = []
    inside_tag = False
    partial_tag = ""
    for char  in line:
        if char == filters[0] and not inside_tag:
            inside_tag = True
        elif char == filters[1] and inside_tag:
            contents.append(partial_tag)
            partial_tag = ""
            inside_tag = False
        elif inside_tag:
            partial_tag += char
        else:
            substring += 1
    if partial_tag:
        print("Warning: unclosed tag '{}' ".format(partial_tag))
    return contents, substring

感知,因为不需要复杂计算每个括号落在行中的位置,等等 - 你只需要全部。

答案 1 :(得分:0)

我不确定我是否完全理解这一点 - 您想获得[stuff in brackets]everything else?如果你只是解析扁平字符串 - 没有括号中的递归括号 - 你可以做

import re

parse = re.compile(r"\[.*?\]|[^\[]+").findall

然后

>>> parse('[start]go up[wait time=500]go down[p]')
['[start]', 'go up', '[wait time=500]', 'go down', '[p]']

>>> parse('@onclick go up[wait time=500]go down active="False"')
['@onclick go up', '[wait time=500]', 'go down active="False"']

正则表达式翻译为"两个方括号之间的所有内容或任何不包括开头方括号的内容"。

如果这不是您想要的 - 您希望@word成为一个单独的块吗? - 请显示{/ 1}}和string_a 解析的内容!