我是初学程序员,所以这个问题可能听起来微不足道:我有一些文本文件包含制表符分隔的文本,如:
A
B
C
D
E
Run Code Online (Sandbox Code Playgroud)
现在我想生成无序的.html列表,结构如下:
<ul>
<li>A
<ul><li>B</li>
<li>C
<ul><li>D</li>
<li>E</li></ul></li></ul></li>
</ul>
Run Code Online (Sandbox Code Playgroud)
我的想法是写一个Python脚本,但如果有一个更容易(自动)的方式,那也没关系.为了识别缩进级别和项目名称,我将尝试使用此代码:
import sys
indent = 0
last = []
for line in sys.stdin:
count = 0
while line.startswith("\t"):
count += 1
line = line[1:]
if count > indent:
indent += 1
last.append(last[-1])
elif count < indent:
indent -= 1
last = last[:-1]
Run Code Online (Sandbox Code Playgroud)
试试这个(适用于你的测试用例):
import itertools
def listify(filepath):
depth = 0
print "<ul>"*(depth+1)
for line in open(filepath):
line = line.rstrip()
newDepth = sum(1 for i in itertools.takewhile(lambda c: c=='\t', line))
if newDepth > depth:
print "<ul>"*(newDepth-depth)
elif depth > newDepth:
print "</ul>"*(depth-newDepth)
print "<li>%s</li>" %(line.strip())
depth = newDepth
print "</ul>"*(depth+1)
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助
tokenize模块理解您的输入格式:行包含有效的Python标识符,语句的缩进级别很重要。ElementTree模块允许您操作内存中的树结构,因此将树的创建与将其呈现为 html 分开可能会更灵活:
from tokenize import NAME, INDENT, DEDENT, ENDMARKER, NEWLINE, generate_tokens
from xml.etree import ElementTree as etree
def parse(file, TreeBuilder=etree.TreeBuilder):
tb = TreeBuilder()
tb.start('ul', {})
for type_, text, start, end, line in generate_tokens(file.readline):
if type_ == NAME: # convert name to <li> item
tb.start('li', {})
tb.data(text)
tb.end('li')
elif type_ == NEWLINE:
continue
elif type_ == INDENT: # start <ul>
tb.start('ul', {})
elif type_ == DEDENT: # end </ul>
tb.end('ul')
elif type_ == ENDMARKER: # done
tb.end('ul') # end parent list
break
else: # unexpected token
assert 0, (type_, text, start, end, line)
return tb.close() # return root element
Run Code Online (Sandbox Code Playgroud)
任何提供.start()、.end()、.data()、.close()方法的类都可以用作例如TreeBuilder,您可以即时编写 html,而不是构建树。
要解析标准输入并将 html 写入标准输出,您可以使用ElementTree.write():
import sys
etree.ElementTree(parse(sys.stdin)).write(sys.stdout, method='html')
Run Code Online (Sandbox Code Playgroud)
输出:
<ul><li>A</li><ul><li>B</li><li>C</li><ul><li>D</li><li>E</li></ul></ul></ul>
Run Code Online (Sandbox Code Playgroud)
您可以使用任何文件,而不仅仅是sys.stdin/sys.stdout.
注意:要在 Python 3 上写入 stdout,请使用sys.stdout.buffer或encoding="unicode"由于字节/Unicode 的区别。
| 归档时间: |
|
| 查看次数: |
1191 次 |
| 最近记录: |