首页 / PYTHON / 使用Python优化字符串解析
使用Python优化字符串解析
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了使用Python优化字符串解析,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3751字,纯文字阅读大概需要6分钟。
内容图文
![使用Python优化字符串解析](/upload/InfoBanner/zyjiaocheng/681/a7d7c4c42dba4d9bad6af6b0be535438.jpg)
我的字符串格式为“ AB(AB(DDC)C)A(BAAC)DAB(ABC)”.
>每个字符代表一个元素(A,B,C或D).
>在右括号之间,每个元素都有一个子元素(可能不存在).
例如,具有“ AB(AB(DDC)C)A(BAAC)DA”,顶层将是AB(AB(DDC)C)A(BAAC)DA. [A,B,A,D,A],相应的子代将为[无,AB(DDC)C,BAAC,无,无].儿童也将被递归解析.
我在这里实现了一个解决方案:
def parse_string(string):
i = 0
parsed = []
while i < len(string):
if string[i] in ('A', 'B', 'C', 'D'):
parsed.append([string[i], None])
i += 1
elif string[i] == '(':
open_brakets = 1
i += 1
j = i
while open_brakets:
if string[j] == '(':
open_brakets += 1
elif string[j] == ')':
open_brakets -= 1
j += 1
# Parse the children as well
parsed[-1][-1] = parse_string(string[i:j - 1])
i = j
else:
i += 1
return parsed
print parse_string('AB(AB(DDC)C)A(BAAC)DAB(ABC)')
尽管我认为这有点丑陋,但我确信它不是很有效.
我想知道是否有一种方法可以使Python更清洁/更快/更优雅?允许使用外部库(特别是如果它们是用C!:-P编写的).
更新资料
其他应该起作用的字符串示例:
> ABC(DAB(ACB)BBB(AAA)ABC)DCB
通常,字符串的长度不受限制,子代的数目,长度,嵌套级别的数目均不受限制.
解决方法:
如果您还需要递归地解析内部括号:
def parse_tree(tree, string, start=0):
index = start
while index < len(string):
current = string[index]
if current == "(":
child = tree[-1][1]
child_parsed = parse_tree(child, string, index+1)
index += child_parsed + 2 # adds 2 for the parentheses
elif current == ")":
break
else:
tree.append((current, []))
index += 1
return index - start
tree = []
print(parse_tree(tree, 'abc(abc(defg)d)de(f)gh'))
可以将其视为状态机.状态机接受节点定义,直到看到一个开放的括号,然后在其中将新的上下文(即递归函数调用)推送到解析堆栈以解析括号的内容.解析内部上下文时,右括号会弹出上下文.
如果您具有更复杂的语法,则可以更好地扩展的另一种选择是使用诸如PyParsing之类的解析库:
from pyparsing import OneOrMore, Optional, oneOf, alphas, Word, Group, Forward, Suppress, Dict
# define the grammar
nodes = Forward()
nodeName = oneOf(list(alphas))
nodeChildren = Suppress('(') + Group(nodes) + Suppress( ')')
node = Group(nodeName + Optional(nodeChildren))
nodes <<= OneOrMore(node)
print(nodes.parseString('abc(abc(defg)d)de(f)gh'))
像PyParsing这样的解析库允许您定义一个易于阅读的说明性语法.
原始非递归解析的答案:一种方法是使用itertools(累积仅来自Python 3.2及更高版本,itertools文档的旧版本为pure python implementation of accumulate).这样可以避免使用索引:
from itertools import takewhile, accumulate
PARENS_MAP = {'(': 1, ')': -1}
def parse_tree(tree, string):
string = iter(string)
while string:
current = next(string)
if current == "(":
child = iter(string)
child = ((c, PARENS_MAP.get(c, 0)) for c in child)
child = accumulate(child, lambda a,b: (b[0], a[1]+b[1]))
child = takewhile(lambda c: c[1] >= 0, child)
child = (c[0] for c in child)
tree[-1][1] = "".join(child)
else:
tree.append([current, None])
print(parse_tree('abc(abc(defg)d)de(f)gh'))
我不确定它是更快还是更优雅,但是我认为使用显式索引更容易编写,理解和修改.
内容总结
以上是互联网集市为您收集整理的使用Python优化字符串解析全部内容,希望文章能够帮你解决使用Python优化字符串解析所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。